【问题标题】:JAVA - Corrupt ZIP file using ZipOutptuStream with FileInputStreamJAVA - 使用带有 FileInputStream 的 ZipOutptuStream 损坏 ZIP 文件
【发布时间】:2017-01-05 18:30:14
【问题描述】:

为什么当通过 servlet 输出流输出时,以下代码会生成损坏的 zip 文件?使用 FileOutputStream 将 ZIP 写入本地磁盘时,输出流似乎没有损坏。

// Create zip stream
ZipOutputStream zos = new ZipOutputStream(this.servletOutputStream);

// prepare a new entry
ZipEntry zipEntry = new ZipEntry(forZip.getName());
zipEntry.setSize(forZip.getTotalSpace());
zipEntry.setTime(System.currentTimeMillis());

// write entry
zos.putNextEntry(zipEntry);

// write the file to the entry
FileInputStream toBeZippedInputStream = new FileInputStream(forZip);
IOUtils.copy(toBeZippedInputStream, zos);
zos.flush();

// close entry
zos.closeEntry();

// close the zip
zos.finish();
zos.close();

this.servletOutputStream.flush();

this.servletOutputStream.close();

// close output stream
IOUtils.closeQuietly(toBeZippedInputStream);

这可能是刷新/关闭流的顺序问题吗?

【问题讨论】:

  • 您可能想刷新toBeZippedInputStream而不是zos
  • 您如何确定流数据已损坏?
  • 您如何确定问题不在您未提供的代码中?如果是这段代码有问题,那么准备和提交minimal reproducible example 应该不会太难。
  • 特别是,我的第一个猜测是在 Zip 数据之前将某些内容写入输出流。
  • 您可能想了解what getTotalSpace() does。您应该完全删除该行;您不需要明确设置 ZipEntry 的大小。

标签: java servlets fileinputstream zipoutputstream


【解决方案1】:

在刷新 zip 流之前尝试关闭 zip 条目

// close entry
zos.closeEntry();

zos.flush();

在编码风格上,使用try-with-resources确保资源正确关闭。

【讨论】:

  • 我不建议冲洗。在我的情况下,它导致 servlet 中的输出损坏。只使用 finish() 帮助了我。
【解决方案2】:

我看到的一个潜在问题是要压缩的各个条目不是唯一的。如果您在此代码中循环,forZip.getName() 可能有重复。

【讨论】:

  • 这是关于原始问题的问题,而不是答案。请删除此内容,并将其添加到此线程的 cmets 部分。
猜你喜欢
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2014-08-09
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多