java.util.zip-ZipInputStream v.s.ZipFile
我有一些关于java.util.zip-ZipInputStream v.s.ZipFile,java,thread-safety,io,zip,Java,Thread Safety,Io,Zip,我有一些关于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"/> <compone
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"/>
我知道中央zip目录放在zip文件的末尾,但是里面的文件条目有顺序。我也知道依赖订单是一个丑陋的想法,但我只想把所有的事实都记在心里
问题2。如果我使用ZipFile
(我更喜欢),数百次调用getInputStream()
对性能有什么影响?它会比ZipInputStream解决方案慢很多吗?zip仅打开一次,并且ZipFile
由RandomAccessFile
支持-这是否正确?
我假设阅读是这样的:
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
while((entry = zis.getNextEntry()) != null)
{
//read from zis until available
}
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));
}
第三季度。从同一ZipFile
中检索的输入流是否线程安全(例如,我可以同时读取不同线程中的不同条目)?有任何表现处罚吗
谢谢你的回答 Q1:是的,添加条目的顺序相同 问题2:请注意,由于zip存档文件的结构和压缩,没有一种解决方案是完全流式的;它们都有一定程度的缓冲。如果您查看JDK源代码,那么实现会共享大部分代码。虽然索引允许查找与条目对应的块,但并没有真正的随机访问内容。因此,我认为不应该存在有意义的绩效差异;特别是操作系统无论如何都会缓存磁盘块。您可能只想测试性能,用一个简单的测试用例来验证这一点
问题3:我不会指望这一点;很可能他们不是。如果您真的认为并发访问会有帮助(主要是因为解压是CPU限制的,所以可能会有帮助),我会尝试在内存中读取整个文件,通过ByteArrayInputStream公开,并构造多个独立的读卡器。关于Q3,中的经验表明,即使在不相关的流上操作,zlib也不是线程安全的,也就是说,它有一些不正确的共享静态。未经验证,只是一个警告。我测量到,仅使用
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);
(不要在同一个类中运行它们。创建两个不同的类并分别运行它们)使用ZipFile.getInputStream()比使用新的ZipInputStream()要快得多。你自己试试。嗨,斯塔克斯曼!我只是在检查JDK6中ZipFile$ZipFileInputStream的实现。这是由ZipFile.getInputStream返回的,它有同步,但我真的不知道它有多可靠。是的,我不能肯定它是非线程安全的。另一个更危险的部分是底层的原生zlib库,我怀疑它不是线程安全的。通过痛苦的经历,我可以证明它不是线程安全的。我的直觉是ZipFile正在读取zip索引,而ZipInputStream正在“循环”整个zip文件,读取一个又一个文件,FWIW。
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);