3

我正在编写一个工具来在 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到另一个对象的正确或惯用方法是什么?

4

2 回答 2

9

我找到了避免错误的解决方法。通过创建一个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(例如:评论、额外)。API 文档并不清楚这是否重要。

于 2012-08-02T14:56:40.830 回答
0

要保留 zip 条目的元数据,请使用 ZipEntry 的“复制构造函数”创建它:

ZipEntry newEntry = new ZipEntry(entry); 

然后您可以只修改名称或评论等,其他所有内容都将从给定的entry.

您还可以查看可以从 Java 填充DocX文件的 Docmosis。

于 2012-08-08T01:03:12.067 回答