java.util.zip - ZipInputStream v.s. ZipFile的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java.util.zip - ZipInputStream v.s. ZipFile的相关的知识,希望对你有一定的参考价值。
我对java.util.zip
库有一些一般性的问题。我们基本上做的是导入和导出许多小组件。以前这些组件是使用单个大文件导入和导出的,例如:
<component-type-a id="1"/>
<component-type-a id="2"/>
<component-type-a id="N"/>
<component-type-b id="1"/>
<component-type-b id="2"/>
<component-type-b id="N"/>
请注意,导入期间组件的顺序是相关的。
现在每个组件都应该占用自己的文件,该文件应该是外部版本的,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
解决方案慢得多吗?拉链仅打开一次,ZipFile
由RandomAccessFile
支持 - 这是正确的吗?我认为阅读是这样的:
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无论如何都会对磁盘块进行缓存。您可能只想测试性能以通过简单的测试用例来验证这一点。
Q3:我不指望这个;而且很可能他们不是。如果你真的认为并发访问会有所帮助(主要是因为解压缩是CPU绑定的,所以它可能有帮助),我会尝试在内存中读取整个文件,通过ByteArrayInputStream公开,并构建多个独立的读者。
我测量只用ZipInputStream
列出文件比用ZipFile
慢8倍。
long t = System.nanoTime();
ZipFile zip = new ZipFile(jarFile);
Enumeration<? extends ZipEntry> 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也不是线程安全的,即它有一些不正确的共享静态。没有证明,只是一个警告。
以上是关于java.util.zip - ZipInputStream v.s. ZipFile的的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在使用 java.util.zip.ZipFile 打开空 ZIP 文件时出现异常?
如何解决 java.util.zip.ZipException?
为啥我的 java.util.zip 函数显示不一致的行为?
java.util.zip获取Zip文件条目InputStream