Java 从 ZipInputStream 条目创建 InputStream [英] Java create InputStream from ZipInputStream entry
问题描述
我想编写一个方法,从单个 InputStream 读取 ZIP 中的多个 XML 文件.
I would like to write a method that read several XML files inside a ZIP, from a single InputStream.
该方法将打开一个 ZipInputStream,并在每个 xml 文件上获取相应的 InputStream,并将其提供给我的 XML 解析器.这是该方法的骨架:
The method would open a ZipInputStream, and on each xml file, get the corresponding InputStream, and give it to my XML parser. Here is the skeleton of the method :
private void readZip(InputStream is) throws IOException {
ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
if (entry.getName().endsWith(".xml")) {
// READ THE STREAM
}
entry = zis.getNextEntry();
}
}
有问题的部分是//READ THE STREAM".我有一个可行的解决方案,它包括创建一个 ByteArrayInputStream,并将它提供给我的解析器.但它使用缓冲区,对于大文件,我得到一个 OutOfMemoryError.这是代码,如果有人仍然感兴趣:
The problematic part is the "// READ THE STREAM". I have a working solution, which consist to create a ByteArrayInputStream, and feed my parser with it. But it uses a buffer, and for large files I get an OutOfMemoryError. Here is the code, if someone is still interested :
int count;
byte buffer[] = new byte[2048];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((count = zis.read(buffer)) != -1) { out.write(buffer, 0, count); }
InputStream is = new ByteArrayInputStream(out.toByteArray());
理想的解决方案是将原始 ZipInputStream 提供给解析器.它应该可以工作,因为如果我只是使用扫描仪打印条目内容,它就可以工作:
The ideal solution would be to feed the parser with the original ZipInputStream. It should works, because it works if I just print the entry content with a Scanner :
Scanner sc = new Scanner(zis);
while (sc.hasNextLine())
{
System.out.println(sc.nextLine());
}
但是...我目前使用的解析器(jdom2,但我也尝试使用 javax.xml.parsers.DocumentBuilderFactory)在解析数据后关闭流:/.所以我无法获得下一个条目并继续.
But... The parser I'm currently using (jdom2, but I also tried with javax.xml.parsers.DocumentBuilderFactory) closes the stream after parsing the data :/ . So I'm unable to get the next entry and continue.
所以最后的问题是:
- 有人知道不关闭流的 DOM 解析器吗?
- 还有其他方法可以从 ZipEntry 获得 InputStream 吗?
谢谢.
推荐答案
您可以包装 ZipInputStream 并拦截对 close()
的调用.
You could wrap the ZipInputStream and intercept the call to close()
.
这篇关于Java 从 ZipInputStream 条目创建 InputStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!