如何使用非ASCII文件名创建Windows本机兼容的Zip文件

时间:2015-07-19 03:11:04

标签: java windows utf-8 filenames non-latin

我们的团队有一个程序可以生成用Java编写的PDF。 PDF可能具有非ASCII文件名,使用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文件?

1 个答案:

答案 0 :(得分: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自解压可执行文件“header”。

回应有问题的评论:

  

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

     

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

     

OS X对文件名编码强制执行UTF-8,因此Java在创建文件名时也应该尊重它。