从ZipInputStream获取特定文件
我可以遍历ZipInputStream
,但是在开始迭代之前,我想获取迭代期间需要的特定文件.我该怎么办?
I can go through ZipInputStream
, but before starting the iteration I want to get a specific file that I need during the iteration. How can I do that?
ZipInputStream zin = new ZipInputStream(myInputStream)
while ((entry = zin.getNextEntry()) != null)
{
println entry.getName()
}
如果要使用的myInputStream
来自磁盘上的真实文件,则可以简单地使用java.util.zip.ZipFile
,它由RandomAccessFile
,并按名称提供对zip条目的直接访问.但是,如果您仅有的是InputStream
(例如,如果您是直接从网络套接字或类似设备收到来的,就在处理流),那么您就必须自己进行缓冲.
If the myInputStream
you're working with comes from a real file on disk then you can simply use java.util.zip.ZipFile
instead, which is backed by a RandomAccessFile
and provides direct access to the zip entries by name. But if all you have is an InputStream
(e.g. if you're processing the stream directly on receipt from a network socket or similar) then you'll have to do your own buffering.
您可以将流复制到一个临时文件,然后使用ZipFile
打开该文件,或者如果您事先知道数据的最大大小(例如,对于预先声明其Content-Length
的HTTP请求),则可以可以使用BufferedInputStream
将其缓冲在内存中,直到找到所需的条目为止.
You could copy the stream to a temporary file, then open that file using ZipFile
, or if you know the maximum size of the data in advance (e.g. for an HTTP request that declares its Content-Length
up front) you could use a BufferedInputStream
to buffer it in memory until you've found the required entry.
BufferedInputStream bufIn = new BufferedInputStream(myInputStream);
bufIn.mark(contentLength);
ZipInputStream zipIn = new ZipInputStream(bufIn);
boolean foundSpecial = false;
while ((entry = zin.getNextEntry()) != null) {
if("special.txt".equals(entry.getName())) {
// do whatever you need with the special entry
foundSpecial = true;
break;
}
}
if(foundSpecial) {
// rewind
bufIn.reset();
zipIn = new ZipInputStream(bufIn);
// ....
}
(我还没有亲自测试过这段代码,您可能会发现有必要在bufIn
和第一个zipIn
之间使用commons-io CloseShieldInputStream
之类的东西来关闭第一个zip流.在倒回之前不关闭基础bufIn
).
(I haven't tested this code myself, you may find it's necessary to use something like the commons-io CloseShieldInputStream
in between the bufIn
and the first zipIn
, to allow the first zip stream to close without closing the underlying bufIn
before you've rewound it).