3

我有一个 ZipInputStream ,其中包含许多要对其应用转换的 XML 文件。以下代码加载 XSLT 和 ZIP 文件并循环通过 ZIP 条目,尝试将转换应用于每个条目。但是,在执行转换后,转换函数似乎正在关闭输入流,导致 getNextEntry() 函数失败,因为流已关闭。

有没有解决这个问题的简单方法(保持输入流打开,允许 ZipInputStream 移动到下一个条目)或者我在这里错过了更基本的东西?

TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource(xsltFileName));

FileInputStream fis = new FileInputStream(fileName);
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry ze = null;

while ((ze = zis.getNextEntry()) != null)
{
    String newFileName = ze.getName();
    transformer.transform(new StreamSource(zis), new StreamResult(new FileOutputStream(newFileName)));
}

我试图寻找解决方案,但似乎没有提出任何有意义的建议。我很感激任何想法或反馈。

4

5 回答 5

5

一种可能的解决方案是扩展 ZipInputStream (它不是最终的)并覆盖 close 方法以不做任何事情。当然,您需要确保自己关闭它。您可以使用第二个自定义关闭方法来完成此操作,该方法只需调用 super.close()。

class MyZIS extends ZipInputStream {

    public MyZIS(InputStream in) {
        super(in);
    }

    @Override
    public void close() throws IOException {
    }

    public void myClose() throws IOException {
        super.close();
    }
}
于 2012-10-19T16:10:42.737 回答
1

通常接受的协议是“创建输入流的人应该在使用后关闭它”,并且您的 XSLT 处理器(Xalan?)似乎没有遵循这个约定。如果是这种情况,那么一种解决方法(除了移动到不同的 XSLT 处理器!)是编写一个过滤器流,它包装 ZipInputStream 并将所有调用传递给底层 ZipInputStream,除了它拦截的 close() 调用。

于 2012-10-19T13:57:13.793 回答
0

您实际上应该使用 ZipFile 类来读取 zip 存档。然后,您将获得 zip 条目的输入流,如下所示:

zipfile.getInputStream(zipEntry);
于 2012-10-19T14:45:51.167 回答
-1

也许您需要做的是将 zip 输入读入临时缓冲区,然后将其用作转换器的源。我的理解是转换器需要读取整个流以确定转换应该是什么,因此,即使它没有关闭输入流,下一次读取也会遇到 EOF。

也许是这样的?(未进行任何优化)

    byte[] bytes = new byte[(int) entry.getSize()];
    zis.read(bytes);
    ByteArrayInputStream out = new ByteArrayInputStream(bytes);
    transformer.transform(new StreamSource(zis), new StreamResult(new FileOutputStream(newFileName)));    }
于 2012-10-19T16:51:41.327 回答
-1

您可以设置一个属性:IsStreamOwner,当它为 false 时,基础流将不会关闭。

于 2014-09-16T12:13:55.203 回答