Preferred way to use Java ZipOutputStream and BufferedOutputStream

后端 未结 2 1663
终归单人心
终归单人心 2021-02-01 00:37

In Java does it matter whether I instantiate a ZipOutputStream first, or the BufferedOutputStream first? Example:

FileOutputStream dest = new FileOutputStream(fi         


        
相关标签:
2条回答
  • 2021-02-01 01:17

    You should always wrap the BufferedOutputStream with the ZipOutputStream, never the other way around. See the below code:

    FileOutputStream fos = new FileOutputStream("hello-world.zip");
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    ZipOutputStream zos = new ZipOutputStream(bos);
    
    try {
        for (int i = 0; i < 10; i++) {
            // not available on BufferedOutputStream
            zos.putNextEntry(new ZipEntry("hello-world." + i + ".txt"));
            zos.write("Hello World!".getBytes());
            // not available on BufferedOutputStream
            zos.closeEntry();
        }
    }
    finally {
        zos.close();
    }
    

    As the comments say the putNextEntry() and closeEntry() methods are not available on the BufferedOutputStream. Without calling those methods ZipOutputStream throws an exception java.util.zip.ZipException: no current ZIP entry.

    For the sake of completeness, it is worth noting that the finally clause only calls close() on the ZipOutputStream. This is because by convention all built-in Java output stream wrapper implementations propagate closing.

    EDIT

    I just tested it the other way around. It turns out that wrapping a ZipOutputStream with BufferedOutputStream and then only calling write() on it (without creating / closing entries) will not throw a ZipException. Instead the resulting ZIP file will be corrupt, without any entries inside it.

    0 讨论(0)
  • 2021-02-01 01:26

    You should:

    ZipOutputStream out =  new ZipOutputStream(new BufferedOutputStream(dest));
    

    because you want to buffer the writing to the disc (because this is much more efficient in big data blocks than in a lot of little ones).


    This

    new BufferedOutputStream(new ZipOutputStream(dest));
    

    would buffer before zip compression. But this all happens in the memory and does not need buffering because a lot of little memory accesses are about the same speed as a few big ones. In memory general the needed time is proportional to the number of bytes read/write.

    As mentioned in the comments:

    The methods of ZipOutputStream which are not part of BufferedOutputStream would not be available also. E.g. putNextEntry and closeEntry.

    0 讨论(0)
提交回复
热议问题