0

我的要求是 zip 文件中有一个 .xls 文件,可以使用 URL 下载。因为我想在内存中读取这个 excel 文件(供以后处理),而不是在本地下载 zip,所以我使用了 ZipInputStream,这就是我的代码的主要部分的样子:

String finalUrl = "https://server/myZip.zip"
URL url = new URL(finalUrl);
InputStream inputStream = new BufferedInputStream(url.openStream());
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry file;
try {
  while ((file = zis.getNextEntry()) != null) {
    if (file.getName().endsWith(".xls")) {
      log.info("xls file found");
      log.info("file name : {}", file.getName());
      byte excelBytes[] = new byte[(int)file.getSize()];
      zis.read(excelBytes);
      InputStream excelInputStream = new ByteArrayInputStream(excelBytes);
      HSSFWorkbook wb = new HSSFWorkbook(excelInputStream);
      HSSFSheet sheet = wb.getSheetAt(8);
      log.info("sheet : {}", sheet.getSheetName());
    }
    else {
      log.info("xls file not found");
    }
  }
}
finally{
   zis.close();
}

但不幸的是,我收到以下错误:

java.lang.ArrayIndexOutOfBoundsException: Index -3 out of bounds for length 3247

注意:.xls 文件大小约为 2MB,zip 文件没有任何复杂的结构,例如子目录或多个文件。

这里的任何帮助将不胜感激。谢谢!

4

1 回答 1

0

感谢@PJ Fanning 强调这一点,问题在于zis.read(excelBytes)不能保证读取所有字节。改用后IOUtils.toByteArray,问题解决了。正确的代码是:

String finalUrl = "https://server/myZip.zip"
URL url = new URL(finalUrl);
InputStream inputStream = new BufferedInputStream(url.openStream());
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry file;
try {
  while ((file = zis.getNextEntry()) != null) {
    if (file.getName().endsWith(".xls")) {
      log.info("xls file found");
      log.info("file name : {}", file.getName());
      byte excelBytes[] = IOUtils.toByteArray(zis);
      InputStream excelInputStream = new ByteArrayInputStream(excelBytes);
      HSSFWorkbook wb = new HSSFWorkbook(excelInputStream);
      HSSFSheet sheet = wb.getSheetAt(8);
      log.info("sheet : {}", sheet.getSheetName());
    }
    else {
      log.info("xls file not found");
    }
  }
}
finally{
   zis.close();
}
于 2021-09-15T12:28:19.240 回答