【问题标题】:ZipInputStream is closes when reading first ZipEntry of Excel files读取 Excel 文件的第一个 ZipEntry 时关闭 ZipInputStream
【发布时间】:2022-01-25 21:53:26
【问题描述】:

我将 excel 文件的 zip 作为多部分文件上传,但是当我创建第一个文件的 Workbook 对象时,流被关闭并且我无法读取下一个文件。 它适用于 zip 中的单个文件,但不适用于多个文件。 有人可以帮忙吗? TIA。

       try {
            ZipInputStream zis = new ZipInputStream(multipartFile.getInputStream());
            ZipEntry zipEntry;
            while((zipEntry = zis.getNextEntry()) != null) {
                XSSFWorkbook workbook = new XSSFWorkbook(zis);
                readWorkbook(workbook);
            }
            zis.close();
        } catch (Exception e) {
            LOG.error(e);
        }

【问题讨论】:

  • 您尝试过 POI 5.2.0(最新版本)吗? - ` public XSSFWorkbook(InputStream is) throws IOException { this(is, false); }` -- false 控制输入流是否关闭

标签: java spring-boot apache-poi zipinputstream multipartfile


【解决方案1】:

唯一的选择是包装它,这样你就可以拦截close() 并防止它关闭压缩包。比如:

var wrapper = new FilterInputStream(zis) {
  @Override public void close() {}
}

然后将wrapper 而非zis 传递给new XSSFWorkbook

注意:警告 - 您的代码受到严重阻碍,本质上是错误的。您需要确保在最后关闭该 ZipInputStream,而您现在不这样做。你的异常处理真的很糟糕。您必须以硬退出结束所有异常块,仅记录它是不够的。 throw new RuntimeException("uncaught", e); 是后备选项(许多 IDE 默认附带 e.printStackTrace()。这是一个已知的极其愚蠢的默认设置,请更新您的 IDE 以解决此问题。同时使用 try-with-resources 以确保始终发生关闭(只需调用 @ 987654328@ 不够好;如果发生异常,将不会调用您在 sn-p 中的 close() 调用。

【讨论】:

  • 谢谢!这行得通..也感谢您的建议,这是一个示例代码,只是为了显示问题。实际代码与此不同。
【解决方案2】:

从 Zipfile 读取时,您有一个用于存档的 InputStream。然后你遍历那里的不同条目,对于每个条目,你再次有一个 InputStream 可供读取。确保不要关闭条目的 InputStreams,因为该事件将关闭存档流。

在您的情况下,可能是 XSSFWorkbook 的构造函数或 readWorkbook 方法正在关闭流。

【讨论】:

  • 它是关闭流的 XSSFWorkbook 的构造函数。需要一些解决方法来处理它。
  • 这是不正确的 - 最新的 POI 代码不会关闭流
猜你喜欢
  • 2011-05-20
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-01
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多