1

我们的团队有一个程序可以生成用 Java 编写的 PDF。可能具有非 ASCII 文件名的 PDF 使用 Apache Commons Compress 进行压缩。然后将 zip 文件上传到 S3 以供 Windows 和 Mac 客户端下载。

在 Mac 上使用本机工具解压缩时,会使用正确的文件名重新创建文件。但是,当尝试使用本机 Windows UI 工具解压缩时,文件名创建不正确。

压缩过程是:

    import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 

我添加了以下代码,它仍然无法正常工作,在 Windows 上显示不可读的字符:

    zipFile.setEncoding("UTF-8");
    zipFile.setUseLanguageEncodingFlag(true);     
    zipFile.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPoli‌​cy.ALWAYS);

如何创建 Mac 和 Windows 都可以使用的 zip 文件?

4

1 回答 1

2

根据 Apache Commons Compress 页面:( https://commons.apache.org/proper/commons-compress/zip.html )

Windows 的“压缩文件夹”功能不识别任何标志或额外字段,并使用平台默认编码创建档案 - 并期望档案在读取时采用该编码。

如果 Windows 的“压缩文件夹”是您的主要消费者,那么您最好的选择是将编码显式设置为目标平台。您可能希望启用 Unicode 额外字段的创建,以便支持它们的工具正确提取文件名。

所以:

如果您知道您的 Windows 用户位于地球的一个有限区域,并且您的文件名仅限于该区域(例如所有拉丁语),您可以听取 Apache 的建议并为文件名编码定义一个 8 位代码页,这将受到尊重OS X 的解压缩。但是,这意味着它不能在不同地区的 Windows 机器上运行,或者不小心使用了稍微不同的代码页(北美与西欧)。

明智的选择是在 Windows 上使用替代存档工具,并可能使用替代存档格式。也许您可以通过在 zip 文件中添加合适的提取工具来为 Windows 创建自解压档案。例如,您可以使用此处的粗略说明在 Java 中创建自解压 7zip 存档:http: //sourceforge.net/p/sevenzip/discussion/45798/thread/de8aa3c6

伪格式为:

7z.sfx + config.txt + your-created-archive.7z your-created-archive.exe

7z.sfx与 7zip 一起分发的 7zip 自解压可执行“头文件”在哪里?

针对有问题的评论:

Windows 使用 UTF-16 作为文件名,AFAIK 在其 Java 调用的低级 API 中使用 UTF-16。但是,Windows 控制台非常损坏并且不能快速支持 UTF-8。

(Java 在内部也为 String 对象使用 UTF-16)

OS X 对文件名编码强制使用 UTF-8,因此 Java 在创建文件名时也应该尊重这一点。

于 2015-07-22T07:48:10.557 回答