Java ZipInputStream(InputStream,Charset)错误地解码ZipEntry文件名

Java ZipInputStream(InputStream,Charset)错误地解码ZipEntry文件名,java,character-encoding,zipinputstream,Java,Character Encoding,Zipinputstream,Java7应该修复一个旧问题,即使用UTF-8以外的字符集解包zip归档文件。这可以通过构造函数ZipInputStream(InputStream,Charset)实现。到目前为止,一切顺利。当显式设置ISO-8859-1字符集时,我可以解压缩包含文件名和UMLAUT的zip存档 但是问题在于:当使用ZipInputStream.getnextry()在流上迭代时,条目的名称中有错误的特殊字符。在我的例子中,umlaut“ü”被替换为“?”字符,这显然是错误的。有人知道怎么解决这个问题吗?显然

Java7应该修复一个旧问题,即使用UTF-8以外的字符集解包zip归档文件。这可以通过构造函数
ZipInputStream(InputStream,Charset)
实现。到目前为止,一切顺利。当显式设置ISO-8859-1字符集时,我可以解压缩包含文件名和UMLAUT的zip存档

但是问题在于:当使用
ZipInputStream.getnextry()
在流上迭代时,条目的名称中有错误的特殊字符。在我的例子中,umlaut“ü”被替换为“?”字符,这显然是错误的。有人知道怎么解决这个问题吗?显然
ZipEntry
忽略了其底层
ZipInputStream
Charset
。这看起来像是另一个与zip相关的JDK bug,但我可能也做错了什么

...
zipStream = new ZipInputStream(
    new BufferedInputStream(new FileInputStream(archiveFile), BUFFER_SIZE),
    Charset.forName("ISO-8859-1")
);
while ((zipEntry = zipStream.getNextEntry()) != null) {
    // wrong name here, something like "M?nchen" instead of "München"
    System.out.println(zipEntry.getName());
    ...
}

天哪,我玩了大约两个小时,但就在我最终将问题发布到这里的五分钟后,我偶然发现了答案:我的zip文件不是用ISO-8859-1编码的,而是用Cp437编码的。因此构造函数调用应该是:

zipStream = new ZipInputStream(
    new BufferedInputStream(new FileInputStream(archiveFile), BUFFER_SIZE),
    Charset.forName("Cp437")
);

现在它就像一个符咒。抱歉打扰你了。我希望这对其他面临类似问题的人有所帮助。

我认为你可以接受这个答案是正确的,尽管这篇文章是你自己写的:我也有同样的问题,我花了几个小时来解决它。解决方法非常简单,只需对我的cp852使用MS-DOS编码,而不是win CP1250是的,这是非常相同的问题和相同的解决方案,只是不是针对英文MS-DOS代码页437,而是针对中欧代码页852。当然,确切的解决方案始终取决于所讨论的ZIP归档文件在/中生成的环境和工具。Java行为可以说是不一致的,因为规范似乎非常清楚,在未设置“语言编码标志(EFS)”时,Cp437是默认的。“D.1 ZIP格式历史上仅支持原始IBM PC字符编码集,通常称为IBM代码页437…D.2如果通用位11未设置,则文件名和注释应符合原始ZIP字符编码”我对您的注释进行了投票,因为链接是非常有用的资源。公平地说,Java并不声称要尝试检测编码,甚至不读取EFS,但清楚地表明它使用UTF-8作为默认值,这在今天是可以理解的,特别是因为它也是JAR文件的默认值。因此,在Java中,在调用
ZipInputStream
构造函数之前,您必须了解编码。很公平。让您的评论如此有用的是知道Cp437实际上是一个默认值,所以这应该是出现任何问题时首先尝试的编码之一。Java SE6的最佳实践是什么?(除了升级到SE7:)对于SE6:我测试了将VM参数
zip.altEncoding
zip.encoding
设置为
Cp437
ISO-8859-1
,这两个参数都无助于读取correctly@basZero:apachecommons Compress工作得很好。不过,我没有找到现成的解决方案。