java.util.zip – ZipInputStream vs ZipFile

我有一些关于java.util.zip库的一般性问题。 我们基本上做的是导入和导出许多小组件。 以前,这些组件是使用单个大文件导入和导出的,例如:

       

请注意,导入期间组件的顺序是相关的。

现在每个组件都应该占用自己的文件,该文件应该是外部版本的,QA-ed,bla,bla。 我们决定导出的输出应该是一个zip文件(包含所有这些文件),我们导入的输入应该是一个类似的zip文件。 我们不想在我们的系统中爆炸zip。 我们不希望为每个小文件打开单独的流。 我目前的问题:

Q1。 ZipInputStream保证zip条目(小文件)的读取顺序与我们使用ZipOutputStream的导出插入的顺序相同吗? 我认为阅读是这样的:

 ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); ZipEntry entry; while((entry = zis.getNextEntry()) != null) { //read from zis until available } 

我知道中央zip目录放在zip文件的末尾,但是内部的文件条目有顺序。 我也知道依靠订单是一个丑陋的想法,但我只想记住所有的事实。

Q2。 如果我使用ZipFile (我更喜欢),调用getInputStream()几百次会对性能产生什么影响? 它会比ZipInputStream解决方案慢得多吗? zip只打开一次, ZipFileRandomAccessFile支持 – 这是正确的吗? 我认为阅读是这样的:

 ZipFile zipfile = new ZipFile(argv[0]); Enumeration e = zipfile.entries();//TODO: assure the order of the entries while(e.hasMoreElements()) { entry = (ZipEntry) e.nextElement(); is = zipfile.getInputStream(entry)); } 

Q3。 从同一个ZipFile线程检索的输入流是否安全(例如,我可以同时读取不同线程中的不同条目)吗? 任何表现处罚?

谢谢你的回答!

Q1:是的,订单与添加条目的顺序相同。

Q2:请注意,由于zip存档文件的结构和压缩,没有一个解决方案正是流媒体; 他们都做了一定程度的缓冲。 如果您查看JDK源代码,实现将共享大多数代码。 内容中没有真正的随机访问,尽管索引确实允许查找与条目对应的块。 所以我认为应该没有有意义的性能差异; 特别是因为OS无论如何都会对磁盘块进行缓存。 您可能只想测试性能以通过简单的测试用例来validation这一点。

Q3:我不会指望这个; 而且很可能他们不是。 如果你真的认为并发访问会有所帮助(主要是因为解压缩是CPU绑定的,所以它可能有帮助),我会尝试在内存中读取整个文件,通过ByteArrayInputStream公开,并构建多个独立的读者。

我测量只用ZipInputStream列出文件比使用ZipFile慢8倍。

  long t = System.nanoTime(); ZipFile zip = new ZipFile(jarFile); Enumeration entries = zip.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); String filename = entry.getName(); if (!filename.startsWith(JAR_TEXTURE_PATH)) continue; textureFiles.add(filename); } zip.close(); System.out.println((System.nanoTime() - t) / 1e9); 

  long t = System.nanoTime(); ZipInputStream zip = new ZipInputStream(new FileInputStream(jarFile)); ZipEntry entry; while ((entry = zip.getNextEntry()) != null) { String filename = entry.getName(); if (!filename.startsWith(JAR_TEXTURE_PATH)) continue; textureFiles.add(filename); } zip.close(); System.out.println((System.nanoTime() - t) / 1e9); 

(不要在同一个类中运行它们。创建两个不同的类并单独运行它们)

关于Q3, JENKINS-14362的经验表明, 即使在不相关的流上运行 ,zlib也不是线程安全的,即它有一些不正确的共享静态。 没有certificate,只是一个警告。