Java ZipInputStream中的XMLEventReader关闭流
我想流式传输一个包含几个非常大(~1G字节)XML文件的ZIP文件。我可以将每个zip文件中的数据读入缓冲区,并从中创建XMLStream——但为了节省内存,我更愿意动态处理数据Java ZipInputStream中的XMLEventReader关闭流,java,xml,stream,zip,Java,Xml,Stream,Zip,我想流式传输一个包含几个非常大(~1G字节)XML文件的ZIP文件。我可以将每个zip文件中的数据读入缓冲区,并从中创建XMLStream——但为了节省内存,我更愿意动态处理数据 @Test public void zipStreamTest() throws IOException, XMLStreamException { FileInputStream fis = new FileInputStream("archive.zip"); ZipInputS
@Test
public void zipStreamTest() throws IOException, XMLStreamException {
FileInputStream fis = new FileInputStream("archive.zip");
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry ei;
while ((ei = zis.getNextEntry()) != null){
XMLEventReader xr = XMLInputFactory.newInstance().createXMLEventReader(zis);
while (reader.hasNext()) {
XMLEvent xe = xr.nextEvent();
// do some xml event processing..
}
zis.closeEntry();
}
zis.close();
}
问题是:在执行zis.closeEntry()时,我得到了一个java.io.IOException:Stream closed
代码>。当我删除该行时,在zis.getnextery()
上抛出相同的错误,如果以前的条目仍然自动打开,它将关闭这些条目
我的XML流读取器似乎正在破坏XML文件末尾的流,因此无法处理zip的其余部分
我是否有实现错误,或者我对流如何工作的概念不正确
注意:为了使这成为一个最小的可复制示例,您只需要一个zip文件“archive.zip”,其中包含任何有效的XML文件(zip中没有子目录!)。然后,您可以使用JUnit运行代码段。您可以尝试使用java.util.zip.ZipFile
为每个条目打开单独的InputStream:
@Test
public void zipStreamTest() throws Exception {
ZipFile zipFile = new ZipFile("archive.zip");
Iterator<? extends ZipEntry> iterator = zipFile.entries().asIterator();
while (iterator.hasNext()) {
ZipEntry ze = iterator.next();
try (InputStream zis = zipFile.getInputStream(ze)) {
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(zis);
while (reader.hasNext()) {
XMLEvent xe = reader.nextEvent();
// do some xml event processing
}
reader.close();
}
}
}
@测试
public void zipStreamTest()引发异常{
ZipFile ZipFile=新ZipFile(“archive.zip”);
迭代器我建议使用ZipFile
而不是ZipInputStream
,如中所建议
但是,如果您正在处理数据流,例如在下载时,因此希望继续使用ZipInputStream
,则应将其包装在getnextery()循环中的from 1中:
while((ei=zis.getnextery())!=null){
XMLEventReader xr=XMLInputFactory.newInstance().createXMLEventReader(新CloseShieldInputStream(zis));
//在这里处理XML
zis.closeEntry();
}
1) 或者您选择的第三方库中的其他类似助手类。不会显示为关闭底层源代码,除非您显式调用其close()
方法,所以我猜您是在调用close()在某个地方。考虑在您的问题中提供一个。我建议使用<代码> zIPFrase<代码>而不是<代码> zIPunPoStuts,如建议的那样,但是如果您正在处理一个数据流,例如下载,因此希望继续使用<代码> zIPunPuthStudio,您应该将它包装为A-(或其他类似的帮助类)。在getnextery()中
loop.@Andreas:非常感谢!您的解决方案非常有效。请将您的解决方案表述为一个答案,以便我能够接受。Re:ZipFile:这是一个显而易见的解决方案,但我的zip源和目标不是文件,而是网络流和/或数据库套接字。我从网络流获取zip,因此ZipFile不是一个合适的工具。一个dreas使用CloseShieldInputStream找到了一个解决方案,该方案使用所需的方法解决了问题。