从ZipInputStream读取到ByteArrayOutputStream [英] Reading from a ZipInputStream into a ByteArrayOutputStream

查看:318
本文介绍了从ZipInputStream读取到ByteArrayOutputStream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to read a single file from a java.util.zip.ZipInputStream, and copy it into a java.io.ByteArrayOutputStream (so that I can then create a java.io.ByteArrayInputStream and hand that to a 3rd party library that will end up closing the stream, and I don't want my ZipInputStream getting closed).

我可能会遗漏一些基本的东西,但是我永远不要在这里输入while循环:

I'm probably missing something basic here, but I never enter the while loop here:

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) {
    // ...
}

我错过了什么可以让我复制流?

What am I missing that will allow me to copy the stream?

修改:

我之前应该提到过这个 ZipInputStream 不是来自文件,所以我认为我不能使用的ZipFile 。它来自通过servlet上传的文件。

I should have mentioned earlier that this ZipInputStream is not coming from a file, so I don't think I can use a ZipFile. It is coming from a file uploaded through a servlet.

另外,我已经调用了 getNextEntry()在获取此代码段之前, ZipInputStream 。如果我不尝试将文件复制到另一个 InputStream (通过上面提到的 OutputStream ),并且只是通过 ZipInputStream 到我的第三方库,库关闭了流,我无法做更多的事情,比如处理流中剩余的文件。

Also, I have already called getNextEntry() on the ZipInputStream before getting to this snippet of code. If I don't try copying the file into another InputStream (via the OutputStream mentioned above), and just pass the ZipInputStream to my 3rd party library, the library closes the stream, and I can't do anything more, like dealing with the remaining files in the stream.

推荐答案

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

Your loop looks valid - what does the following code (just on it's own) return?

zipStream.read(tempBuffer)

如果它正在返回-1,然后在你获得它之前关闭zipStream,所有的赌注都关闭了。是时候使用你的调试器并确保传递给你的是实际有效的。

if it's returning -1, then the zipStream is closed before you get it, and all bets are off. It's time to use your debugger and make sure what's being passed to you is actually valid.

当你调用getNextEntry()时,它是否返回一个值,并且是数据在条目中有意义(即getCompressedSize()是否返回有效值)?如果您只是阅读没有嵌入预读zip条目的Zip文件,那么ZipInputStream将不适合您。

When you call getNextEntry(), does it return a value, and is the data in the entry meaningful (i.e. does getCompressedSize() return a valid value)? IF you are just reading a Zip file that doesn't have read-ahead zip entries embedded, then ZipInputStream isn't going to work for you.

一些有用的花絮关于Zip格式:

Some useful tidbits about the Zip format:

zip文件中嵌入的每个文件都有一个标题。此标头可以包含有用的信息(例如流的压缩长度,它在文件中的偏移量,CRC) - 或者它可以包含一些基本上说'信息不在流标题中的魔术值,你必须检查Zip post-amble'。

Each file embedded in a zip file has a header. This header can contain useful information (such as the compressed length of the stream, it's offset in the file, CRC) - or it can contain some magic values that basically say 'The information isn't in the stream header, you have to check the Zip post-amble'.

每个zip文件都有一个附加到文件末尾的表,其中包含所有zip条目以及真实的数据。最后的表是必需的,其中的值必须正确。相反,不必提供流中嵌入的值。

Each zip file then has a table that is attached to the end of the file that contains all of the zip entries, along with the real data. The table at the end is mandatory, and the values in it must be correct. In contrast, the values embedded in the stream do not have to be provided.

如果使用ZipFile,它会读取zip末尾的表格。如果您使用ZipInputStream,我怀疑getNextEntry()尝试使用流中嵌入的条目。如果未指定这些值,则ZipInputStream不知道流可能有多长。 inflate算法是自终止的(你实际上不需要知道输出流的未压缩长度以便完全恢复输出),但是这个读者的Java版本可能不能很好地处理这种情况。

If you use ZipFile, it reads the table at the end of the zip. If you use ZipInputStream, I suspect that getNextEntry() attempts to use the entries embedded in the stream. If those values aren't specified, then ZipInputStream has no idea how long the stream might be. The inflate algorithm is self terminating (you actually don't need to know the uncompressed length of the output stream in order to fully recover the output), but it's possible that the Java version of this reader doesn't handle this situation very well.

我会说让servlet返回ZipInputStream是相当不寻常的(如果你要接收压缩内容,接收inflatorInputStream会更常见。

I will say that it's fairly unusual to have a servlet returning a ZipInputStream (it's much more common to receive an inflatorInputStream if you are going to be receiving compressed content.

这篇关于从ZipInputStream读取到ByteArrayOutputStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆