views:

2176

answers:

1

Hello all!

I have a problem, which I do not seem to be able to solve... I do a http download of a file, but the CRC32 of the file on the server and on the client do not match. Also, the file has different size, so obviously I must be doing something wrong... when I download via Firefox, the filesize is ok... so I guess it is somewhere in the client code.

I already found http://stackoverflow.com/questions/401748/corrupt-file-when-using-java-to-download-file, but that didn't help me either...

Here's the code:

private void downloadJar(String fileName, long crc32Server) throws IOException {
  System.out.println("Downloading file '" + fileName + "' from server '" + mServer + "'.");
  HttpURLConnection sourceConnection = null;
  BufferedInputStream inputStream = null;
  BufferedWriter fileWriter = null;
  long crc32Client;
  try {
    URL sourceURL = new URL(fileName);
    try {
      sourceConnection = (HttpURLConnection)sourceURL.openConnection();
    }
    catch (MalformedURLException exc) {
      throw new RuntimeException("Configured URL caused a MalformedURLException: ", exc);
    }
    sourceConnection.setRequestProperty("Accept-Encoding", "zip, jar");
    sourceConnection.connect();
    inputStream = new BufferedInputStream(sourceConnection.getInputStream());
    fileWriter = new BufferedWriter(new FileWriter(targetFolder + File.separator + fileName));
    CRC32 crc32 = new CRC32();
    for (int singleByte = inputStream.read(); singleByte != -1; singleByte = inputStream.read()) {
      fileWriter.write(singleByte);
      crc32.update(singleByte);
    }
    crc32Client = crc32.getValue();
  }
  finally {
    if (inputStream != null) {
      inputStream.close();
    }
    if (fileWriter != null) {
      fileWriter.flush();
      fileWriter.close();
    }
    if (sourceConnection != null) {
      sourceConnection.disconnect();
    }
  }
  if (crc32Client != crc32Server) {
    //      deleteFile(fileName);
    throw new IOException("CRC32 did not match for file '" + fileName + "': " + crc32Client + "!="
        + crc32Server);
  }
}
+5  A: 

You should use a BufferedOutputStream instead of a FileWriter/BufferedWriter. In general, *Streams handle raw binary data, while *Writers handle character data (which is an interpretation of the raw binary data for a given character encoding).

Zach Scrivena
Now I get at least the same file size, thank you for the tipp. But the CRC check still fails...
roesslerj
Does the Firefox download give the same CRC32?
Zach Scrivena
Seems to be a problem of different CRC32 calculations, the downloaded file is now binary identical to the one on the server...Thanks for the help so far. I guess now I am on the road again ;-)
roesslerj
Yeah, I was afraid so... there are a bunch of CRC32 formulas. Maybe you could try MD5 or some other cryptographic hash instead.
Zach Scrivena
I got it. I use CRC32 Java Std-Implementation. But when I created the CRC32 on the server, I did the same Stream/Writer mistake... causing different CRC32 as a result! Thanks a lot, I guess I wouldn't have found that easily...
roesslerj