线程安全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文件。我们不想让系统崩溃。我们不希望为每个小文件打开单独的流。我现在的问题是:
问题1。可否ZipInputStream
保证zip条目(小文件)的读取顺序与我们使用ZipOutputStream
的导出所插入的顺序相同?我认为阅读是这样的:
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
while((entry = zis.getNextEntry()) != null)
{
//read from zis until available
}
我知道中央zip目录放在zip文件的末尾,但是里面的文件条目有顺序。我也知道依赖命令是一个丑陋的想法,但我只想记住所有的事实
问题2。如果我使用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));
}
问题3。从同一ZipFile
线程检索的输入流是否安全(例如,我可以同时读取不同线程中的不同条目)?有任何表现处罚吗
谢谢你的回答
# 1 楼答案
使用ZipFile。getInputStream()比使用新的ZipInputStream()快得多。你自己试试吧
# 2 楼答案
关于Q3,JENKINS-14362的经验表明,即使在不相关的流上操作,zlib也不是线程安全的,也就是说,它有一些不正确的共享静态。没有证明,只是一个警告
# 3 楼答案
我测量到,仅仅用
ZipInputStream
列出文件比用ZipFile
列出文件慢8倍及
(不要在同一个班上运行它们。制作两个不同的班并分别运行)
# 4 楼答案
问题1:是的,顺序将与添加条目的顺序相同
问题2:请注意,由于zip存档文件的结构和压缩,没有一种解决方案是完全流式的;它们都有一定程度的缓冲作用。如果您查看JDK源代码,就会发现实现共享了大部分代码。虽然索引允许查找与条目对应的块,但并没有真正的随机访问内容。因此,我认为不应该存在有意义的绩效差异;尤其是操作系统无论如何都会缓存磁盘块。您可能只想测试性能,用一个简单的测试用例来验证这一点
问题3:我不会指望这一点;如果你真的认为并发访问会有帮助(主要是因为解压是CPU限制的,所以可能会有帮助),我会尝试在内存中读取整个文件,通过ByteArrayInputStream公开,并构造多个独立的读卡器