代码之家  ›  专栏  ›  技术社区  ›  alamar

解压缩用i18n文件名的winzip创建的文件?

  •  4
  • alamar  · 技术社区  · 15 年前

    现在人们用winzip创建他们的zip文件,它允许国际化(即非拉丁语:西里尔文、希腊语、中文、你自己命名)文件名。

    不幸的是,试图解包这样的文件会导致麻烦: Unix解压创建垃圾文件和类似“______”的目录。 Java及其JAR命令在这样的档案上失败得很惨。

    有没有一种可以通过编程方式解包这些文件的方法?UNIX或Java。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Cheeso    15 年前

    DotNetZip 支持压缩文件中文件名的Unicode和任意编码,无论是读取还是写入压缩文件。

    这是一个.NET库。对于UNIX的使用,您将需要Mono作为前提条件。

    如果zipfile是由winzip正确构造的,换句话说,如果它符合 the zip spec from PKWare 在解包时,您不需要做任何特殊的工作来指定编码。根据zip规范,zipfiles中的文件名有两种支持的编码: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");
        }
    } 
    

    有一些存档程序可以生成“不符合”W.R.T.编码的压缩包。Winrar就是其中之一-它将创建一个zip,其中文件名在计算机上使用默认编码进行编码。在上海,它将使用CP950,而在冰岛,则是其他地方,而在里斯本,则是其他地方。这里“不符合”的优点是,Windows资源管理器将打开并以这种压缩方式正确显示i18n大小的文件名。换句话说,“不合规”通常是人们想要的,因为Windows(还没有?)。支持UTF-8 zip文件。

    (这一切都与zip file中使用的编码有关,而不是与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是免费的,并且是开源的。

        2
  •  2
  •   alamar    15 年前

    我找到的解决方案是: 如果提供了正确的回退字符集,ApacheCommonsCompress可以很好地解压这样的档案。