【问题标题】:How to create Windows native compatible Zip files with non-ASCII filenames如何使用非 ASCII 文件名创建 Windows 本机兼容的 Zip 文件
【发布时间】:2015-07-19 03:11:04
【问题描述】:

我们的团队有一个程序可以生成用 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 文件?

【问题讨论】:

  • 是的,它是UTF8,什么版本的windows?并非所有窗口都使用 UTF8 进行文件名编码。
  • Windows 7,文件名是 utf-8 编码的,mac 可以正确显示,但是 windows 不能,我应该为 windows 生成不同版本的文件名还是有一些方法可以添加 self-描述关于编码到文件名的元数据,以便平台可以相应地推断?
  • 您是如何生成要在文件名中使用的 utf 非 ascii 字符的?
  • zipFile.putArchiveEntry(new ZipArchiveEntry(filenameDeduper.getUniqueName(metadataModel.getFileName())));我想这等于说 zipFile.putArchiveEntry(new ZipArchiveEntry(javaString))
  • 尝试将文件名放到控制台。它会产生预期的非拉丁字符还是垃圾?据我所见,除非在该函数的某个地方调用其中一个函数不能正确处理 utf8(我相信 utf8 在 java 中是通用的),否则我会不知所措。我能想到的唯一另一件事是操作系统配置为不使用 UTF8 或显示它们。在您知道正确处理 utf8 的不同 Windows 机器上尝试。否则我很茫然。

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


【解决方案1】:

根据 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 自解压可执行“头文件”。

针对有问题的 cmets:

Windows 使用 UTF-16 作为文件名,AFAIK 在 Java 调用的低级 API 中使用 UTF-16。但是,Windows 控制台非常糟糕,不能很快支持 UTF-8。

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

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

【讨论】:

    猜你喜欢
    • 2012-11-09
    • 2014-05-24
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 2023-03-28
    • 2014-09-06
    • 2014-07-09
    • 1970-01-01
    相关资源
    最近更新 更多