我正在尝试从java.util.zip.ZipInputStream中读取单个文件,并将其复制到java.io.ByteArrayOutputStream中(这样我就可以创建一个java.io.ByteArrayInputStream并将其交给第三方库,该库最终将关闭该流,并且我不希望关闭我的ZipInputStream )。
我可能在这里缺少了一些基本的东西,但是我从来没有在这里输入while循环:
ByteArrayOutputStream streamBuilder = new ByteArrayOutputStream();
int bytesRead;
byte[] tempBuffer = new byte[8192*2];
try {
while ((bytesRead = zipStream.read(tempBuffer)) != -1) {
streamBuilder.write(tempBuffer, 0, bytesRead);
}
} catch (IOException e) {
// ...
}我错过了什么能让我复制这条溪流?
编辑:
我应该在前面提到,这个ZipInputStream不是来自一个文件,所以我认为我不能使用ZipFile。它来自一个通过servlet上传的文件。
此外,在进入这段代码之前,我已经在ZipInputStream上调用了ZipInputStream。如果我不尝试将文件复制到另一个InputStream中(通过上面提到的OutputStream ),只需将ZipInputStream传递给第三方库,库就会关闭该流,并且我不能做更多的事情,比如处理流中的其余文件。
发布于 2008-09-16 04:54:35
您的循环看起来是有效的-下面的代码(仅仅是它自己的代码)返回什么?
zipStream.read(tempBuffer)如果它返回-1,那么zipStream在你得到它之前就关闭了,所有的赌注都取消了。现在是使用调试器并确保传递给您的内容实际上是有效的时候了。
当您调用getNextEntry()时,它是否返回一个值,并且条目中的数据是否有意义(即,getCompressedSize()返回一个有效值)?如果您只是在读取一个没有预先读取的Zip条目的zip文件,那么ZipInputStream将不适合您。
关于Zip格式的一些有用的小道消息:
嵌入在zip文件中的每个文件都有一个标头。这个头可以包含有用的信息(例如流的压缩长度,它在文件中的偏移量,CRC)或者它可以包含一些神奇的值,这些值基本上可以说‘信息不在流头中,您必须检查Zip后-amble’。
然后,每个zip文件都有一个表,该表附加到文件的末尾,其中包含所有zip条目以及实际数据。末尾的表是强制性的,其中的值必须是正确的。相反,不需要提供嵌入在流中的值。
如果使用ZipFile,它会读取zip末尾的表。如果使用ZipInputStream,我怀疑getNextEntry()尝试使用嵌入在流中的条目。如果没有指定这些值,那么ZipInputStream就不知道流可能有多长时间。膨胀算法是自终止的(实际上不需要知道输出流的未压缩长度才能完全恢复输出),但是这个读取器的Java版本可能不能很好地处理这种情况。
我要说的是,servlet返回ZipInputStream是非常不寻常的(如果要接收压缩的内容,接收inflatorInputStream就更常见了。)
发布于 2008-09-15 22:47:11
您可能尝试过像这样从FileInputStream中阅读:
ZipInputStream in = new ZipInputStream(new FileInputStream(...));这个不会工作,因为压缩归档文件可以包含多个文件,您需要指定要读取的文件。
您可以使用java.util.zip.ZipFile和一个库(如来自的IOUtils或番石榴ByteStreams )来帮助您复制流。
示例:
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ZipFile zipFile = new ZipFile("foo.zip")) {
ZipEntry zipEntry = zipFile.getEntry("fileInTheZip.txt");
try (InputStream in = zipFile.getInputStream(zipEntry)) {
IOUtils.copy(in, out);
}
}发布于 2008-09-15 21:56:02
我会使用来自commons项目的IOUtils。
IOUtils.copy(zipStream, byteArrayOutputStream);https://stackoverflow.com/questions/67275
复制相似问题