在zip存档中使用Unicode字符表示文件名

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

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

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

这取决于您用于创建存档的代码。 旧的 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构造函数上有一个Charset参数(可以是UTF-8)

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

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(os,charset)构造函数创建以非UTF-8编码的Zip文件,如有必要。

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