【问题标题】:Using Unicode characters for file names inside a zip archive使用 Unicode 字符作为 zip 存档中的文件名
【发布时间】:2012-04-02 10:31:34
【问题描述】:

我正在压缩一个包含一些特殊字符的文件名,例如 Péréquation LES HOPITAUX NEUFS.xls 到另一个文件夹,比如 temp

我可以压缩文件,但问题是文件名自动更改为 P+¬r+¬quation LES HOPITAUX NEUFS.xls.

如何在 zip 存档中支持文件名的 unicode 字符?

【问题讨论】:

标签: java file zip


【解决方案1】:

这在一定程度上取决于您用于创建存档的代码。 旧的 Java 压缩类没有你需要的那么灵活。

您可以使用Apache Commons CompressMichael Simons 写了这段漂亮的代码:

ZipArchiveOutputStream ostream = ...; // Your initialization code here
ostream.setEncoding("Cp437"); // This should handle your "special" characters
ostream.setFallbackToUTF8(true); // For "unknown" characters!
ostream.setUseLanguageEncodingFlag(true);                               
ostream.setCreateUnicodeExtraFields(
    ZipArchiveOutputStream.UnicodeExtraFieldPolicy.NOT_ENCODEABLE);

如果您使用的是 Java 7,那么您终于在 ZipOutputStream constructor 上有一个 Charset 参数(可以是 UTF-8)

无论如何,最大的问题是许多实现不理解 Unicode 编码,因为 原始 ZIP 文件格式是 ASCII 并且没有 Unicode 的官方标准。详情请参阅this post

【讨论】:

  • 在您的流上调用 setEncoding("UTF-8") 或将其作为 FileOutputStream 构造函数的参数提供。无论如何不要忘记答案中指出的兼容性问题!
  • 导入 java.util.zip.ZipOutputStream;是我正在使用的不支持 setEncoding("UTF-8") 的包
  • 如果您不能使用 Java 7,您可以使用 Apache Common Compress 等第 3 方库
  • 某人应该是 Michael Simons:info.michael-simons.eu/2010/01/05/…
  • @zovits 谢谢,现在 someone 有了名字(和应得的学分)!
【解决方案2】:

Zip 规范(历史上)没有指定用于嵌入文件名和 cmets 的字符编码,最初的 IBM PC 字符编码集,通常称为 IBM Code Page 437,应该是唯一的编码支持的。 Jar 规范同时明确指定使用 UTF-8 作为编码对 Jar 文件中的所有文件名和 cmets 进行编码和解码。为此,我们的 java.util.jar 和 java.util.zip 实现严格遵循 Jar 规范,在处理 Jar/Zip 文件中存储的文件名和 cmets 时使用 UTF-8 作为唯一编码。

后果?基于 java.util.jar/zip 的工具无法访问由“传统”ZIP 工具创建的 ZIP 文件,反之亦然,如果文件名包含 Cp437 之间不兼容的字符(作为替代,工具可能只使用默认平台编码)和 UTF-8

对于大多数欧洲人来说,你是“幸运的”:-) 你只需要避免“少数”字符,例如元音变音(好吧,我只是在开玩笑),但对于日语和中文来说,大多数的字符只是运气不好。这就是为什么 bug 4244499 多年来一直是 Top 25 Java Bugs 中的第一名。该错误不再在列表中:-) 它终于在 OpenJDK 7, b57 中“修复”了。我仍然保留快照作为自己的记录/kudo:-)

JDK7 b57 中的解决方案(我会使用“解决方案”而不是“修复”)是在一组新的 ZipInputStream ZipOutStream 和 ZipFile 构造函数中引入特定的“字符集”作为参数,如下所示。

ZipFile(文件,字符集)

ZipInputStream(InputStream, Charset)

ZipOutputStream(OutputStream, Charset)

使用这些新的构造函数,应用程序现在可以通过使用特定编码创建的 ZipInputStream 或 ZipFile 对象访问那些非 UTF-8 的 ZIP 文件,或者通过新的 ZipOutputStream(os, charset) 构造函数,如果需要的话。

zip 是 Jar 工具的精简版,带有“-encoding”选项,以支持条目名称和注释的非 UTF8 编码,它可以作为如何使用新 API 的演示(我用过它作为单元测试)。我还在和自己争论,在 Jar 工具中正式引入“-encoding”是否是个好主意......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    相关资源
    最近更新 更多