我正在编写一个工具,在DOCX文件中进行一些小文本替换,这是一种压缩格式。我的方法是使用ZipEntry
将ZipOutputStream
内容从原始文件中的条目复制到修改后的文件中。对于大多数DOCX文件,这种方法效果很好,但偶尔我会遇到ZipException
关于我写的内容与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{
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
直接复制到另一个{1>}的正确或惯用方法是什么?
答案 0 :(得分:7)
我找到了一种避免错误的解决方法。通过创建只有名称字段集的新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);
if (read > 0) {
outputStream.write(buffer,0,read);
}
}
in.close();
}
outputStream.closeEntry();
}
outputStream.close();
但是,我这种方法丢失了原始ZipEntry
字段中存储的任何元信息(例如:comment,extra)。 API文档不清楚这是否重要。
答案 1 :(得分:0)
要保留zip条目的元数据,请使用ZipEntry的“复制构造函数”创建它:
ZipEntry newEntry = new ZipEntry(entry);
然后,您可以只修改名称或评论等,其他所有内容都将从给定的entry
中复制。
您还可以查看可以从Java填充DocX文件的Docmosis。