Tim*_*tin 5 java zipinputstream xml-parsing
我想编写一个方法,从单个InputStream读取ZIP中的几个XML文件.
该方法将打开ZipInputStream,并在每个xml文件上获取相应的InputStream,并将其提供给我的XML解析器.这是方法的骨架:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
有问题的部分是"// READ THE STREAM".我有一个工作解决方案,它包括创建一个ByteArrayInputStream,并用它提供我的解析器.但它使用缓冲区,对于大文件,我得到一个OutOfMemoryError.这是代码,如果有人仍然感兴趣:
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());
Run Code Online (Sandbox Code Playgroud)
理想的解决方案是使用原始ZipInputStream提供解析器.它应该有效,因为如果我只用扫描仪打印条目内容就可以了:
Scanner sc = new Scanner(zis);
while (sc.hasNextLine())
{
System.out.println(sc.nextLine());
}
Run Code Online (Sandbox Code Playgroud)
但是......我正在使用的解析器(jdom2,但我也尝试使用javax.xml.parsers.DocumentBuilderFactory)在解析数据后关闭流:/.所以我无法获得下一个条目并继续.
最后问题是:
谢谢.
小智 6
Tim 的解决方案的一个小改进:必须在 close() 之前调用 allowToBeClosed() 的问题是它使得在处理异常时正确关闭 ZipInputStream 很棘手,并且会破坏 Java 7 的 try-with-resources 语句。
我建议创建一个包装类,如下所示:
public class UncloseableInputStream extends InputStream {
private final InputStream input;
public UncloseableInputStream(InputStream input) {
this.input = input;
}
@Override
public void close() throws IOException {} // do not close the wrapped stream
@Override
public int read() throws IOException {
return input.read();
}
// delegate all other InputStream methods as with read above
}
Run Code Online (Sandbox Code Playgroud)
然后可以安全地使用如下:
try (ZipInputStream zipIn = new ZipInputStream(...))
{
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
ZipEntry entry;
while (null != (entry = zipIn.getNextEntry()))
{
if ("file.xml".equals(entry.getName())
{
Document doc = db.parse(new UncloseableInputStream(zipIn));
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4014 次 |
| 最近记录: |