Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monitor GZip Download Progress in Java

I download some files in my java app and implemented a download monitor dialog. But recently I compressed all the files with gzip and now the download monitor is kind of broken.

I open the file as a GZIPInputStream and update the download status after every kB downloaded. If the file has a size of 1MB the progress goes up to e.g. 4MB which is the uncompressed size. I want to monitor the compressed download progress. Is this possible?

EDIT: To clarify: I'm reading the bytes from the GZipInputStream which are the uncompressed bytes. So that does not give me the right filesize at the end.

Here is my code:

URL url = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.connect();
...
File file = new File("bibles/" + name + ".xml");
if(!file.exists())
    file.createNewFile();
out = new FileOutputStream(file);
in = new BufferedInputStream(new GZIPInputStream(con.getInputStream()));

byte[] buffer = new byte[1024];
int count;
while((count = in.read(buffer)) != -1) {
    out.write(buffer, 0, count);
    downloaded += count;
    this.stateChanged();
}

...

private void stateChanged() {
    this.setChanged();
    this.notifyObservers();
}

Thanks for any help!

like image 865
dbrettschneider Avatar asked Oct 07 '22 20:10

dbrettschneider


1 Answers

According to the specification, GZIPInputStream is a subclass of InflaterInputStream. InflaterInputStream has a protected Inflater inf field that is the Inflater used for the decompression work. Inflater.getBytesRead should be particularly useful for your purposes.

Unfortunately, GZIPInputStream does not expose inf, so probably you'll have to create your own subclass and expose the Inflater, e.g.

public final class ExposedGZIPInputStream extends GZIPInputStream {

  public ExposedGZIPInputStream(final InputStream stream) {
    super(stream);
  }

  public ExposedGZIPInputStream(final InputStream stream, final int n) {
    super(stream, n);
  }

  public Inflater inflater() {
    return super.inf;
  }
}
...
final ExposedGZIPInputStream gzip = new ExposedGZIPInputStream(...);
...
final Inflater inflater = gzip.inflater();
final long read = inflater.getBytesRead();
like image 51
SJuan76 Avatar answered Oct 10 '22 01:10

SJuan76