我正在将文件名压缩包含一些特殊字符,例如PéréquationLESHOPITAUX NEUFS.xls 到另一个文件夹,例如 temp 。
我可以压缩文件,但问题是文件名自动更改为 P +¬r+¬quationLESHOPITAUX NEUFS.xls 。
如何在zip存档中支持文件名的unicode字符?
答案 0 :(得分:16)
这取决于您用于创建存档的代码。 旧 Java压缩类不是那么灵活。
您可以使用Apache Commons Compress。 Michael 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”是个好主意......