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);
2条答案
按热度按时间vsaztqbk1#
zip规范(历史上)没有指定嵌入文件名和注解使用什么字符编码,原始的ibmpc字符编码集(通常称为ibm代码页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多年来一直是前25个java bug中的第一名。虫子已经不在电脑上了list:-)它最终在openjdk7、b57中被“修复”。我仍然保留一个快照作为记录/kudomyself:-)
jdk7 b57中的解决方案(我将使用“solution”而不是“fix”)是引入一组新的zipinputstream、zipoutstream和zipfile构造函数,并使用一个特定的“charset”作为参数,如下所示。
zipfile(文件,字符集)
zipinputstream(输入流,字符集)
zipoutputstream(输出流,字符集)
有了这些新的构造函数,应用程序现在可以通过zipinputstream或使用特定编码创建的zipfile对象访问那些非utf-8 zip文件,或者在必要时通过新的zipinputstream(os,charset)构造函数创建以非utf-8编码的zip文件。
zip是jar工具的一个精简版本,带有“-encoding”选项以支持条目名称和注解的非utf8编码,它可以作为如何使用新api的演示(我将它用作单元测试)。我仍在和自己争论是否正式将“-编码”引入jar工具是个好主意。。。
yftpprvb2#
这在一定程度上取决于您用来创建存档的代码。旧的java压缩类没有您需要的那么灵活。
您可以使用apachecommons压缩。迈克尔·西蒙斯写了一段很好的代码:
如果您使用的是Java7,那么您终于有了
Charset
zipoutputstream构造函数上的参数(可以是utf-8)不管怎么说,最大的问题是许多实现不理解unicode编码,因为原始的zip文件格式是ascii,并且没有unicode的官方标准。更多详情请参见本帖。