6.3.3 压缩文件处理
Java标准库中的java.util.zip包用于对压缩文件进行处理。Java 7对这一部分功能的更新也比较多。在对文件进行压缩时,允许选择压缩时缓存的中间结果的输出方式,这体现在java.util.zip.Deflater类的deflate方法增加了一个参数来表示不同的输出方式。默认的方式是Deflater.NO_FLUSH,该方式由压缩者来确定输出缓存的中间结果的具体时机。在这种方式下,压缩者可以自由决定缓存中数据的大小,因此通常可以获得最佳的性能。第二种输出方式是Deflater.SYNC_FLUSH,这种方式在每次调用deflate方法时自动清空内部缓冲区,把压缩的中间结果输出。这种方式的好处在于,如果有解压缩程序正在等待压缩之后的输出结果,及时地清空缓冲区可以让解压缩程序更早地开始工作,有利于提高解压缩程序的工作效率。不过这种方式会对压缩性能产生影响。最后一种输出方式是Deflater.FULL_FLUSH,这种方式除了清空缓冲区之外,同时还重置压缩者的内部状态。如果解压缩的程序发现压缩的结果不正确,可以使用此方式来调用deflate方法,要求压缩者重新进行压缩操作。这种方式对性能的影响最大,只在必要时才使用。
与Deflater类对应的java.util.zip.DeflaterOutputStream类的对象在创建时增加了一个参数syncFlush,用来表示对Deflater类的对象所缓存的中间结果的处理方式。如果syncFlush的值为true,那么在调用DeflaterOutputStream类的对象的flush方法来清空其本身的内部缓冲区之前,会先按照SYNC_FLUSH的方式清空对应的Deflater类的对象所缓存的中间结果。
在Java 7之前,压缩文件中的文件名和注释都使用默认编码格式UTF-8。这种UTF-8格式可能造成通过Java压缩的文件无法被其他工具打开。为了解决这个问题,Java 7允许在创建压缩文件时显式地指定文件名和注释所用的字符集。这体现在java.util.zip.ZipFile、java.util.zip.ZipInputStream和java.util.zip.ZipOutputStream类的构造方法中都增加了一个java.nio.charset.Charset类的对象作为参数。这个Charset类的对象就表明了压缩文件中文件名和注释所用的编码字符集。通过Java产生的压缩文件中也包含了相关的元数据,用来表示压缩时的文件名和注释所使用的字符集。
除了上面这些比较大的改动之外,还有一些相关的小改动,包括:Java 7支持大于4 GB的压缩文件的处理;ZipFile类实现了java.io.Closeable接口,从而可以在try-with-resources语句中使用;ZipFile类多了一个方法getComment,用来获取在创建压缩文件时通过ZipOutputStream类的setComment方法所添加的文件注释;如果java.util.zip.GZIPInputStream类在处理压缩文件时遇到了格式不正确的压缩文件,会抛出更加具体的java.util.zip.ZipException异常。
在集合类方面,java.util.Collections类增加了两个新的方法emptyIterator和emtpy-Enumeration,用来返回空的迭代器对象和列举对象。