在zip存档中使用Unicode字符作为文件名

时间:2012-04-02 10:31:34

标签: java file zip

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

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

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

2 个答案:

答案 0 :(得分:16)

这取决于您用于创建存档的代码。 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

答案 1 :(得分:7)

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

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

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

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

ZipFile(File,Charset)

ZipInputStream(InputStream,Charset)

ZipOutputStream(OutputStream,Charset)

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

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