ZipInputStream 在读取 Excel 个文件的第一个 ZipEntry 时关闭

ZipInputStream is closes when reading first ZipEntry of Excel files

我正在将 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);
        }

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

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

唯一的选择是将其包裹起来,这样您就可以拦截 close() 并防止它关闭 zip。类似于:

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 以及确保关闭始终发生(仅调用 close() 是不够的;如果发生异常,您在代码段中的 close() 调用将不会被调用。