在内存中写入具有给定字节数组的ZipEntry

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在内存中写入具有给定字节数组的ZipEntry相关的知识,希望对你有一定的参考价值。

我有一个非常令人困惑的问题,希望我能在这里得到一些想法。

我的问题很简单,但我还没有找到解决方案。

我想创建一个包含ZipEntry的简单ZIP文件。 ZipEntry由给定的字节数组创建(保存在带有Hibernate的Postgres-DB中)。

当我将此字节数组放入ZipOutputStream.write(..)时,创建的ZIP文件总是损坏。我究竟做错了什么?

之后,ZIP文件将传输到FTP服务器。

ByteArrayOutputStream bos = new ByteArrayOutputStream();
final ZipOutputStream zipOut = new ZipOutputStream(bos);
String filename = "test.zip";

for(final Attachment attachment : transportDoc.getAttachments()) {
    log.debug("Adding "+attachment.getFileName()+" to ZIP file /tmp/"+filename);

    ZipEntry ze = new ZipEntry(attachment.getFileName());
    zipOut.putNextEntry(ze);
    zipOut.write(attachment.getFileContent());
    zipOut.flush();
    zipOut.closeEntry();
}

zipOut.close();
org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("/tmp/"+filename), bos.toByteArray());

我很困惑,因为当我更换

zipOut.write(attachment.getFileContent()); //This is the byte array from db

zipOut.write("Bla bla".getBytes());

有效!

但是来自DB的字节数组不能被破坏,因为它可以写入文件中

org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("/tmp/test.png"), attachment.getFileContent());

没有问题。这是一个正确的文件。

我希望你有一些想法。

提前致谢。

编辑:

我试图离线修复ZIP文件,然后显示以下消息:

zip warning: no end of stream entry found: cglhnngplpmhipfg.png

(这个png文件是byte-Array-File)

简单的unzip-command输出如下:

unzip created.zip 
Archive:  created.zip
error [created.zip]:  missing 2 bytes in zipfile
  (attempting to process anyway)
error [created.zip]:  attempt to seek before beginning of zipfile
  (please check that you have transferred or created the zipfile in the
appropriate BINARY mode and that you have compiled UnZip properly)
  (attempting to re-compensate)
replace cglhnngplpmhipfg.png? [y]es, [n]o, [A]ll, [N]one, [r]ename: y
  inflating: cglhnngplpmhipfg.png    
  error:  invalid compressed data to inflate
file #2:  bad zipfile offset (local header sig):  24709
  (attempting to re-compensate)
  inflating: created.xml

编辑2:

当我将此文件写入文件系统并通过InputStream将此文件添加到ZIP时,它也不起作用!但是文件系统上的文件没问题。我可以毫无问题地打开图像。它非常令人困惑

File tmpAttachment = new File("/tmp/"+filename+attachment.getFileName());
FileUtils.writeByteArrayToFile(tmpAttachment, attachment.getFileContent());
FileInputStream inTmp = new FileInputStream(tmpAttachment);
int len;
byte[] buffer = new byte[1024];
while ((len = inTmp.read(buffer)) > 0) {
     zipOut.write(buffer, 0, len);
}
inTmp.close();

编辑3:

仅当我尝试添加“复杂”文件(如png或pdf)时才会出现此问题。如果我在其中放入一个txt文件,它就可以了。

答案

问题不在Zip-Library本身。

这是使用错误模式传输到外部FTP服务器。 (不是二进制)。

感谢你的帮助。

另一答案

closeEntry()之前尝试flush()。您还可以尝试使用ze.setSize(attachment.getFileContent().length)明确指定条目的大小。

以上是关于在内存中写入具有给定字节数组的ZipEntry的主要内容,如果未能解决你的问题,请参考以下文章

如何在不写入输出流的情况下从 ZipInputStream 获取每个 ZipFile 条目的字节/内容?

h5py 可以从内存中的字节数组加载文件吗?

如何将 NAudio WaveStream 写入内存流?

网络中的对象写入

C++:在进程内存中搜索

内存映射文件和单个块的原子写入