4

如今,人们使用 WinZIP 创建他们的 ZIP 存档,它允许国际化(即非拉丁语:西里尔文、希腊文、中文,随你所想)文件名。

可悲的是,尝试解压缩此类文件会导致麻烦:UNIX 解压缩会创建垃圾命名的文件和目录,例如“®£¤ ©¤¥èì”。Java 及其 jar 命令在此类档案中惨遭失败。

有没有一种可行的方法来以编程方式解压这些文件?UNIX 或 Java。

4

2 回答 2

3

DotNetZip支持 zip 文件中文件名的 unicode 和任意编码,用于读取或写入 zip。

这是一个 .NET 库。对于 Unix 使用,您需要 Mono 作为先决条件。

如果 zipfile 是由 WinZip 正确构建的,换句话说,如果它符合PKWare 的 zip 规范,那么在解压缩时您不需要做任何特殊的工作来指定编码。根据 zip 规范,有两种支持的编码用于 zipfile 中的文件名:UTF-8 和 IBM437。这些编码中的一种或另一种的使用在 zip 元数据中指定,任何 zip 库都可以检测和使用它。DotNetZip 在读取兼容的 zip 时会自动检测到它。像这样:

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");
    }
} 

有些存档程序会生成“不符合”wrt 编码的 zip。WinRar 就是其中之一 - 它会创建一个 zip,其中的文件名以计算机上使用的默认编码进行编码。在上海,它将使用 cp950,而在冰岛,将使用其他设备,而在里斯本,将使用其他设备。此处“不合规”的优点是 Windows 资源管理器将打开并正确显示此类 zip 中的 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 文件 - “不兼容”的 zip。

DotNetZip 是免费且开源的。

于 2009-12-06T12:39:30.070 回答
2

我找到的解决方案:如果提供正确的后备字符集,Apache commons-compress 可以很好地解压缩此类档案。

于 2009-12-02T15:32:08.990 回答