遇到的问题之“一个压缩流,多个文件流,在循环文件流时进行文件读时后执行下一个文件流会报错:java.io.IOException: Stream closed”

一、问题

遇到的问题之“一个压缩流,多个文件流,在循环文件流时进行文件读时后执行下一个文件流会报错:java.io.IOException: Stream closed”

二、原因

易宝接口【文件-下载】返回一个压缩流,使用了ZipInputStream zis = new ZipInputStream(result)类来打开ZIP文件,将其中的一个条目作为Excel文件打开。

在读取ZIP文件时,使用getNextEntry()方法来获取到ZIP文件中的下一个条目,逐个读取ZIP文件中的条目并打开它们。

在逐个循环过程中调用WorkbookFactory.create(zis)方法时,可能会导致流关闭。

这是因为WorkbookFactory.create()方法会尝试读取整个输入流

由于在调用getNextEntry()方法时,ZipInputStream已经指向了ZIP文件中的下一个条目,因此在调用WorkbookFactory.create()方法时,流已经关闭。

因此报错:java.io.IOException: Stream closed

 

三、解决方案

如果你需要获取下一个XLSX文件的内容,你需要重新创建一个ZipInputStream并指定相应的输入流

@Test
public void wzwDevelopGptFileDownloadTest()
{
   // 调用易宝接口 获取【文件-下载】返回的压缩流,前面还有条件封装因为我这里不是特别全且重点不是这里,就没有写了,可以质询易宝相关技术人员
YosDownloadResponse response = yopClient.download(request); YosDownloadInputStream result = null; try { // 及时关闭文件流,避免连接泄漏 result = response.getResult(); ZipInputStream zis = new ZipInputStream(result); ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { if (entry.getName().endsWith(".xls") || entry.getName().endsWith(".xlsx")) { System.out.println("entry.getName() = " + entry.getName()); // 新建文件流,避免异常:java.io.IOException: Stream closed Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(IOUtils.toByteArray(zis))); Sheet sheet = workbook.getSheetAt(0); // 获取行数 int rowNum = sheet.getLastRowNum(); Row row = null; for (int i = 1; i < rowNum + 1; i++) { row = sheet.getRow(i); if (row == null) { break; } int cellNum = 0; // 数据日期 Cell dataDateCell = row.getCell(cellNum++); String dataDateStr = ExcelUtils.getCellTrimValue(dataDateCell); System.out.println("dataDateCell = " + dataDateCell); System.out.println("dataDateStr = " + dataDateStr); if (StringUtils.isEmpty(dataDateStr)) { break; } } } } /* // 下载压缩包到指定位置 File file = new File("D:/financeExcel/2.zip"); FileOutputStream fileOutputStream = new FileOutputStream(file); IOUtils.write(IOUtils.toByteArray(result), fileOutputStream); fileOutputStream.close();*/ zis.close(); } catch (Exception e) { System.out.println("error when download, ex:" + e); } finally { if (null != result) { try { result.close(); } catch (IOException e) { } } } }

 

 

posted @ 2024-05-08 08:26  骚哥  阅读(23)  评论(0编辑  收藏  举报