views:

136

answers:

3

When downloading a rar file from the internet with the code below, the downloaded file is larger than it actually is. Not sure what causes this?

        bis = new BufferedInputStream(urlConn.getInputStream());
        bos = new BufferedOutputStream(new FileOutputStream(outputFile));

        eventBus.fireEvent(this, new DownloadStartedEvent(item));

        int read;
        byte[] buffer = new byte[2048];
        while ((read = bis.read(buffer)) != -1) {
            bos.write(buffer);
        }

        eventBus.fireEvent(this, new DownloadCompletedEvent(item));
+4  A: 

You are writing a full buffer to the output with every write, even if the read(byte[]) operation didn't completely fill it.

Also, since you are reading into a byte[] already, the buffered streams are just counter-productive overhead. Use buffered streams with the single-byte read() and write() methods.

Here is a better pattern to follow.

InputStream is = urlConn.getInputStream();
try {
  FileOutputStream os = new FileOutputStream(outputFile);
  try {
    byte[] buffer = new byte[2048];
    while (true) {
      int n = is.read(buffer);
      if (n < 0)
        break;
      os.write(buffer, 0, n);
    }
    os.flush();
  } finally {
    os.close();
  }
} finally {
  is.close();
}
erickson
+2  A: 

Try using the call to BufferedOutputStream write that takes a length

bos.write(buffer, 0, read)

karoberts
+2  A: 

Don't reinvent the wheel: use the Jakarta Commons IO library, which has already implemented (and debugged!) this code. Specifically, look at IOUtils.copy()

Oh yeah, as erickson shows, you need to close your streams after using them. IOUtils also has a method to do this.

Anon
yes streams are closed in finally block, but didn't paste it for brevity.Looking at the commons util, very intresting
nkr1pt