首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从ZipInputStream读取到ByteArrayOutputStream

从ZipInputStream读取到ByteArrayOutputStream
EN

Stack Overflow用户
提问于 2008-09-15 21:41:21
回答 10查看 51K关注 0票数 20

我正在尝试从java.util.zip.ZipInputStream中读取单个文件,并将其复制到java.io.ByteArrayOutputStream中(这样我就可以创建一个java.io.ByteArrayInputStream并将其交给第三方库,该库最终将关闭该流,并且我不希望关闭我的ZipInputStream )。

我可能在这里缺少了一些基本的东西,但是我从来没有在这里输入while循环:

代码语言:javascript
复制
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传递给第三方库,库就会关闭该流,并且我不能做更多的事情,比如处理流中的其余文件。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2008-09-16 04:54:35

您的循环看起来是有效的-下面的代码(仅仅是它自己的代码)返回什么?

代码语言:javascript
复制
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就更常见了。)

票数 9
EN

Stack Overflow用户

发布于 2008-09-15 22:47:11

您可能尝试过像这样从FileInputStream中阅读:

代码语言:javascript
复制
ZipInputStream in = new ZipInputStream(new FileInputStream(...));

这个不会工作,因为压缩归档文件可以包含多个文件,您需要指定要读取的文件。

您可以使用java.util.zip.ZipFile和一个库(如来自的IOUtils番石榴ByteStreams )来帮助您复制流。

示例:

代码语言:javascript
复制
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);
    }
}
票数 7
EN

Stack Overflow用户

发布于 2008-09-15 21:56:02

我会使用来自commons项目的IOUtils

代码语言:javascript
复制
IOUtils.copy(zipStream, byteArrayOutputStream);
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档