将ZipEntry复制到新ZipFile的惯用方法是什么?
我正在编写一个工具来在DOCX文件中进行一些小文本替换,这是一种压缩格式。 我的方法是使用ZipOutputStream
将ZipEntry
内容从原始文件中的条目复制到修改后的文件中。 对于大多数DOCX文件,这种方法很有效,但偶尔我会遇到ZipException
有关我写的内容与ZipEntry
包含的元信息之间的差异(通常是压缩大小的差异)。
这是我用来复制内容的代码。 为简洁起见,我删除了error handling和文档处理; 到目前为止,我还没有遇到过文档条目的问题。
ZipFile original = new ZipFile(INPUT_FILENAME); ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(OUTPUT_FILE)); Enumeration entries = original.entries(); byte[] buffer = new byte[512]; while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry)entries.nextElement(); if ("word/document.xml".equalsIgnoreCase(entry.getName())) { //perform special processing } else{ outputStream.putNextEntry(entry); InputStream in = original.getInputStream(entry); while (0 < in.available()){ int read = in.read(buffer); outputStream.write(buffer,0,read); } in.close(); } outputStream.closeEntry(); } outputStream.close();
将ZipEntry
对象从一个ZipFile
直接复制到另一个ZipFile
的正确或惯用方法是什么?
我找到了一个避免错误的解决方法。 通过创建一个只有名称字段集的新ZipEntry
,我可以无问题地复制内容。
ZipFile original = new ZipFile(INPUT_FILENAME); ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(OUTPUT_FILE)); Enumeration entries = original.entries(); byte[] buffer = new byte[512]; while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry)entries.nextElement(); if ("word/document.xml".equalsIgnoreCase(entry.getName())) { //perform special processing } else{ // create a new empty ZipEntry ZipEntry newEntry = new ZipEntry(entry.getName()); // outputStream.putNextEntry(entry); outputStream.putNextEntry(newEntry); InputStream in = original.getInputStream(entry); while (0 < in.available()){ int read = in.read(buffer); outputStream.write(buffer,0,read); } in.close(); } outputStream.closeEntry(); } outputStream.close();
但是,我这种方法丢失了存储在原始ZipEntry
字段中的任何元信息(例如:comment,extra)。 API文档不清楚这是否重要。
要保留zip条目的元数据,请使用ZipEntry的“复制构造函数”创建它:
ZipEntry newEntry = new ZipEntry(entry);
然后,您可以只修改名称或注释等,其他所有内容都将从给定entry
复制。
您还可以查看可以从Java填充DocX文件的Docmosis。