0

I am trying to copy a zip file while is being read but the problem is that the copy is not the same as the source, even if the number of bytes are the same. Anyone can see/explain what I'm doing wrong? Thanks!

File fileIn = new File("In.zip");
File fileOut = new File("Out.zip");
final OutputStream out = new FileOutputStream(fileOut);
final AtomicInteger totalBytesRead = new AtomicInteger();
BufferedInputStream copy = new BufferedInputStream(new FileInputStream(fileIn)) {
    @Override
    public synchronized int read(byte[] b, int off, int len) throws IOException {
        int total = super.read(b, off, len);
        if (total != -1) {
            totalBytesRead.addAndGet(total);
            out.write(b, 0, total);
        }
        return total;
    }
};
ZipInputStream zipIn = new ZipInputStream(copy);
ZipEntry zipEntry = null;
while ((zipEntry = zipIn.getNextEntry()) != null) {
    zipIn.closeEntry();
}
IOUtils.copy(copy, new OutputStream() {
    @Override
    public void write(int b) throws IOException {
    }
});
zipIn.close();
out.close();
System.out.println("Expected: " + fileIn.length() + ", Actual: " + totalBytesRead);
System.out.println(FileUtils.contentEquals(fileIn, fileOut));

The output is:

Expected: 3695, Actual: 3695
false
bajistaman
  • 62
  • 8
  • It seems copying the file should be more intuitive here. https://stackoverflow.com/questions/106770/standard-concise-way-to-copy-a-file-in-java – Admit Jan 04 '18 at 17:28
  • Also, why won't you compare fileIn with fileOut? – Admit Jan 04 '18 at 17:33
  • It is being compared by: FileUtils.contentEquals(fileIn, fileOut) – bajistaman Jan 04 '18 at 18:13
  • The InputStream is never reset prior to calling IOUtils.copy, and `out.write` is ignoring the `off` argument. Why do it in such a roundabout way? Why not just copy the file, then go through it as needed? Note that copying a file can be one with [a single method](https://docs.oracle.com/javase/9/docs/api/java/nio/file/Files.html#copy-java.nio.file.Path-java.nio.file.Path-java.nio.file.CopyOption...-). – VGR Jan 04 '18 at 19:13
  • It is meant to be done for a big file so trying to avoid reading it more times than needed – bajistaman Jan 04 '18 at 19:34

1 Answers1

0

You aren't reading the ZIP at all, you're only enumerating its entries, and you therefore aren't copying during reading either, and you are doing another copy after all this. Try actually reading the zip entries, and remove the subsequent IOUtils.copy() call.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks for answering but in order to go through the zip entries I am actually reading the zip file even if I don't read the entries, I have included the last copy becase before that it was missing a few bytes (Expected: 3695, Actual: 3567) – bajistaman Jan 04 '18 at 18:10