解压后打开/下载 zip 文件时出现问题 (Java/ZipInputStream)
背景
目前,我尝试通过带有 HTTP 请求的 HTTP servlet 获取 zip 文件。收到的 zip 文件包含三个不同的文件。这些文件包含我想要过滤掉的信息,并且从源头执行此操作不是一个选项(事实就是如此,尽管我知道它会好得多)。
因为我无法从源头过滤掉文件中的一些信息,文件是从头开始构建的,所以我的解决方案是解压缩文件,将这三个文件作为字符串读取,然后过滤它们。最后“重建”所有内容为“zipfile”(inputStream)并返回inputStream。
问题
目前,我已经创建了一个类来处理文件的解压缩和过滤。最后我只想返回包含 zip 文件和其中的三个文件的新 inputStream。
我已经将 HTTP 实体中的内容获取到 inputStream 中,解压缩此 inputStream 并将三个文件作为三个字符串获取。为了只是尝试看看这项工作是否有效,我目前不想做更多的事情,只是解压缩它们并关闭 inputStream 并返回它。但是,当我返回 inputStream 时,这确实会导致异常:
java.io.IOException: Attempted read on closed stream.
这是因为 inputStream 是在我下面介绍的函数之外使用。当我关闭 zipInputStream 时,我可能也会关闭 inputStream 以进行进一步的工作。
当前代码
public InputStream convertInputStream(HttpEntity entity)
{
InputStream inputStream = null;
try
{
inputStream = entity.getContent();
}
catch (IOException e11)
{
}
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
Vector <String>entryVector = new Vector<String>();
ZipEntry entry;
try
{
String entryValue;
while((entry = zipInputStream.getNextEntry()) != null)
{
System.out.println("Unzipping file: " + entry.getName() + "...");
byte [] buf = new byte[(int) entry.getSize()];
zipInputStream.read(buf);
entryValue = new String(buf);
entryVector.add(entryValue);
zipInputStream.closeEntry();
}
}
catch(IOException e)
{
System.out.println("error in getting next entry.");
}
finally
{
try
{
zipInputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("Unzipping done!");
}
return inputStream;
}
我希望我能够尽可能清楚地表达这一点。我仍然可以看到,当我无法在该函数之外显示整个解决方案时,这是非常难以理解的。
The background
Currently, I try to get a zip-file through a HTTP-servlet with a HTTP-request. The received zip-file contains three different files. These files contain information I want to filter out and doing this from the source is not an option (that's just how it is, though I am aware it would be much better).
Because I cant filter out some information in the file from the source, where the file is build from the beginning, my solution is to decompress the file, read these three files as strings and then filter them. In the end "rebuild" all as a "zipfile" (inputStream) and return the inputStream.
The problem
Currently, I've made a class to handle the decompression and filtering of the file. In the end I just want to return the new inputStream containing the zip-file and the three files inside.
I've come as far as get the content from the HTTP entity into a inputStream, decompress this inputStream and get the three files as three strings. To just try to see if this work, I currently don't want to do more than just decompress them and just close the inputStream and return it.. This does however cause an exception when I return the inputStream:
java.io.IOException: Attempted read on closed stream.
This is because the inputStream is used outside the function I present below. As I close the zipInputStream, I probably also closes the inputStream for further work.
The current code
public InputStream convertInputStream(HttpEntity entity)
{
InputStream inputStream = null;
try
{
inputStream = entity.getContent();
}
catch (IOException e11)
{
}
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
Vector <String>entryVector = new Vector<String>();
ZipEntry entry;
try
{
String entryValue;
while((entry = zipInputStream.getNextEntry()) != null)
{
System.out.println("Unzipping file: " + entry.getName() + "...");
byte [] buf = new byte[(int) entry.getSize()];
zipInputStream.read(buf);
entryValue = new String(buf);
entryVector.add(entryValue);
zipInputStream.closeEntry();
}
}
catch(IOException e)
{
System.out.println("error in getting next entry.");
}
finally
{
try
{
zipInputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("Unzipping done!");
}
return inputStream;
}
I hope I manage to express this as clear as possible. I can still see that this is very confusing to understand when I can't show the whole solution outside this function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在您打印“解压缩文件”的地方,您实际上并没有解压缩任何内容。如果您想这样做,则需要使用 read() 函数从 ZipInputStream 读取条目的内容并将其写入文件。
编辑:
您可以尝试将(压缩的)zip 文件从输入流读取到字节数组中。然后在该数组上创建一个 ByteArrayInputStream,然后将 ZipInputStream 包裹在该数组周围。然后您可以安全地关闭输入流,而无需关闭底层流。
另外,请确保文件的字符串内容确实有用。 new String(byte[]) 使用默认编码创建一个字符串,因此这很可能是无用的。
Where you print "unzipping file", you are not actually unzipping anything. If you want to do that, you need to read the content of the entry from the ZipInputStream using the read() function and write that to a file.
EDIT:
You can try reading the (compressed) zip file from the input stream into a byte array. Then create a ByteArrayInputStream on that array and then wrap your ZipInputStream around that. Then you can safely close the input stream without closing the underlying stream.
Also, make sure that the file's content as String is actually useful. new String(byte[]) creates a string using the default encoding, so this may very well be useless.
所以你不是通过网络“下载”?下载是指将文件从 zip 存档解压到本地硬盘吗?
您可以使用以下方法轻松解压缩 zip 文件:
该方法返回一个 File,它是解压缩文件的根目录。
也许更详细地询问您想要做什么的问题是个好主意。 ATM 机上的每个人都在猜测您要做什么,而不是致力于解决方案。
So you're not "downloading" via network? By download you mean to decompress files from a zip-archive to your local hard-disk?
You can easily decompress a zip file with these methods:
The method returns you a File, which is the root of the decompressed files.
Perhaps it would be a good idea to ask your question more detailed on what you are trying to do. ATM everybody is guessing what you are trying to do instead of working on a solution.
我认为您需要读取每个条目的内容,然后调用entry.closeEntry()
I think that you need to read the contents on each entry and then call entry.closeEntry()
听起来您正在尝试下载 zip 文件,同时以二进制和解压缩形式保存它。如果是这种情况,我会说先以二进制形式下载它,然后再将其单独解压缩到文件磁盘。
如果您两者都不想要,那么您可以选择您想要执行的操作,或者通过将普通流写入磁盘来获取二进制 zip 文件(无需使用 ZipInputStream);或者使用 ZipInputStream 并从每个条目读取数据并将其写入磁盘(但不要使用纯输入流写入磁盘)。
It sounds like you are trying to download the zip file whilst saving it simultaneously in binary and unzipped form. If that is the case, I would say download it first in binary form, then unzip it separately file disk afterwards.
If you don't want both, then you can choose which one you want to do, either by writing the plain stream to disk to get a binary zip file (no need to use a ZipInputStream); or by using a ZipInputStream and reading the data from each entry and writing it to disk (but don't use the plain input stream for writing to disk).