-->

Android Decompress downloaded .xml.gz file

2020-07-19 03:35发布

问题:

I am trying to programmatically decompress a .xml.gz file. It seems to be all pretty straightforward as there are many examples available on the internet which tell you how to decompress a .gz file. However, every-time I try to do it, I get an exception: java.io.IOException: unknown format (magic number d4d4).

I'm trying to do this in an Android app, is it supposed to be done differently from the way its done otherwise in Java?

I'm following this example code available here.

Anyone have any idea what I'm doing wrong here? Also, I'm decompressing the file after I have downloaded it from the a web server. The download seems to have worked fine.

回答1:

Found a nice way of downloading an decompressing at the same time. It works like a breeze.

protected String doInBackground(String... sUrl) {
    try {
        URL url = new URL(sUrl[0]);
        URLConnection connection = url.openConnection();
        InputStream stream = connection.getInputStream();
        stream = new GZIPInputStream(stream);
        InputSource is = new InputSource(stream);
        InputStream input = new BufferedInputStream(is.getByteStream());
        OutputStream output = new FileOutputStream("Path to the file");
        byte data[] = new byte[2097152];
        long total = 0;
        int count;

        while ((count = input.read(data)) != -1) {
            total += count;
            output.write(data, 0, count);
        }

        output.flush();
        output.close();
        input.close();
    } catch (BufferOverflowException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

Reference: http://abhirampal.com/2012/05/17/android-download-decompress-gzip/



回答2:

Here is a way to do it with Retrofit:

public interface DownloadApi {
    @Streaming
    @GET("/download")
    Call<ResponseBody> download();
}

private Retrofit getRetrofitClient() {
    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    Retrofit.Builder builder =  new Retrofit.Builder()
        .baseUrl(API_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create());

     return builder
        .client(httpClient.build())
        .build();
}

public void download() {
    DownloadApi api = getRetrofitClient().create(DownloadApi.class);
    Call<ResponseBody> call = api.download();

    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response.isSuccessful()) {
                unzipAndWriteResponseBodyToDisk(response.body());
            } else {
                //TODO
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            //TODO
        }
    });
}

 private boolean unzipAndWriteResponseBodyToDisk(ResponseBody responseBody) {
    try {
        InputStream compressedInputStream = new GZIPInputStream(responseBody.byteStream());
        InputSource inputSource = new InputSource(compressedInputStream);
        InputStream inputStream = new BufferedInputStream(inputSource.getByteStream());

        File outputFile = new File("path to your file")
        outputFile.getParentFile().mkdirs();
        OutputStream outputStream = new FileOutputStream(outputFile.getAbsoluteFile());

        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, length);
        }

        outputStream.flush();
        outputStream.close();
        inputStream.close();
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}


回答3:

What are the first ten bytes of the .xml.gz file? It looks like the decompressor is trying to tell you that the first two bytes are d4 d4. A .gz file must start with 1f 8b.



标签: android gzip