这些天人们用WinZIP创建他们的ZIP档案,它允许国际化(即非拉丁语:西里尔语,希腊语,中文,你命名)文件名。
可悲的是,尝试解压缩此类文件会导致麻烦: UNIX解压缩创建垃圾命名文件和目录,如“®£¤©¤¥èì”。 Java及其jar命令在这些档案上失败了。
是否有可通过编程方式解压缩此类文件的方法? UNIX或Java。
答案 0 :(得分:3)
DotNetZip支持zipfiles中文件名的unicode和任意编码,用于读取或写入zip文件。
这是一个.NET库。对于Unix的使用,您需要使用Mono作为先决条件。
如果zip文件是由WinZip正确构造的,换句话说,如果它符合the zip spec from PKWare,则在解压缩时指定编码不需要做特别的工作。根据zip规范,zipfile中有两种支持的文件名编码:UTF-8和IBM437。在zip元数据中指定使用这些编码中的一个或另一个,并且任何zip库可以检测并使用它。在阅读兼容的zip时,DotNetZip会自动检测到它。像这样:
using (var zip = ZipFile.Read("thearchive.zip"))
{
foreach (var e in zip)
{
// e.FileName refers to the name on the entry
e.Extract("extract-directory");
}
}
有些存档程序会产生“不符合”的链接w.r.t.编码。 WinRar是一个 - 它将创建一个zip,其文件名以计算机上使用的默认编码进行编码。在上海,它将使用cp950,而在冰岛,还有其他东西,在里斯本,还有其他东西。这里“不合规”的优点是Windows资源管理器将打开并正确显示这种拉链中的i18n化文件名。换句话说,“不合规”通常是人们想要的,因为Windows(还没有?)支持UTF-8 zip文件。
(这都与zipfile中使用的编码有关,而不是zip文件中包含的文件中使用的编码)
zip规范不允许在zip元数据中指定任意文本编码。换句话说,如果在创建zip时使用cp950,那么提取逻辑需要“知道”在解压缩时使用cp950 - zip文件中没有任何内容包含该信息。此外,当然,用于以编程方式提取的zip库必须支持任意编码。据我所知,Java的zip库没有。 DotNetZip呢。像这样:
using (ZipFile zip = ZipFile.Read(zipToExtract,
System.Text.Encoding.GetEncoding(950)))
{
foreach (ZipEntry e in zip)
{
e.Extract(extractDirectory);
}
}
DotNetZip还可以使用任意编码创建zip文件 - “不兼容”拉链。
DotNetZip是免费的,而且是开源的。
答案 1 :(得分:2)
我发现的解决方案: 如果提供正确的回退字符集,Apache commons-compress可以很好地解压缩这些存档。