使用DotNetZip Library解压缩非ASCII字符文件

时间:2011-01-11 06:33:03

标签: c# zip

我正在尝试使用DotNetZip Library解压缩文件。

该文件包含带有丹麦字符的文件夹和文件(æøåÆØÅ)。

TotalCommander,7Zip,Windows自带的zip都能正确提取文件,但DotNetZip Library会破坏丹麦语。

例如:File_æøåÆØÅ.txt变为File_æ¢åÆ¥Å.txt

的{​​}包含¢Ø的{​​{1}}包含¥

代码:

using (var zipFile = ZipFile.Read(@"File_æøåÆØÅ.zip"))
{
     zipFile.ExtractAll(@"File_æøåÆØÅ",
                        ExtractExistingFileAction.OverwriteSilently);
}

我正在使用默认编码(“da-DK”文化),我尝试过其他编码,如UTF8等。

如何解压缩包含丹麦字符文件名的文件?

4 个答案:

答案 0 :(得分:3)

要处理该zip文件,请在阅读zip时明确指定丹麦语代码页:

var encoding = System.Text.Encoding.GetEncoding("da-DK");
using (var zipFile = ZipFile.Read(@"File_æøåÆØÅ.zip", encoding)) {
  zipFile.ExtractAll(@"File_æøåÆØÅ",
                     ExtractExistingFileAction.OverwriteSilently);
} 

您需要明确这样做的原因:
zip规范允许对zip文件中的文件名和注释进行两种文本编码:IBM437和UTF8。当使用这些兼容编码中的任何一个时,zipfile元数据显式指定它。 DotNetZip或任何库可以放心地使用zip文件中指定的编码。

zip文件无法指定不属于这两者的编码。 zip规范没有提供这样做的方法。一些zip库或工具构造的zip文件不符合这方面的规范; zip文件使用“da-DK”或CP950等文本编码。严格来说,他们不符合规范,但工具仍然构建它们。像这样的Zip文件并不罕见。

在这种情况下,某些库或工具会猜测zip文件中使用的编码与计算机上的默认编码相同。这不安全,或保证可行,但它是一个小例子的假设 - 其中zipfile是由本地机器上的不兼容的库或工具创建的。如果使用默认(不合规)文本编码构造zipfile,然后将其从Stokholm发送到上海,则在读取时使用“假定默认编码”策略将失败。

DotNetZip没有做出这样的假设。如果zipfile使用不兼容的文本编码,则zipfile中没有关于使用哪种编码的指示,因此DotNetZip使用标准编码--IBM437--来读取文件。 DNZ无法知道这是“错误的”。如果要覆盖该行为,则需要使用接受不同编码的ZipFile.Read()方法。

这在DotNetZip documentation中有所描述,特别是在ZipFile.ProvisionalAlternateEncoding属性中。

答案 1 :(得分:2)

我使用文件流进行阅读,据我记得它正在运行(DotNetZip-v1.9)。阅读代码:

using (FileStream fs = File.OpenRead(filePath))
{
     ZipFile zf = ZipFile.Read(fs);
     ICollection<ZipEntry> entries = zf.Entries;
     foreach (ZipEntry entry in entries)
     {
          string path = entry.FileName; // 
     }
}

制作zip档案:ZipFile zip = new ZipFile(Encoding.UTF8);

答案 2 :(得分:0)

这听起来就像“DotNetZip”中的一个错误 - 您尝试过SharpZipLibZipPackage(在BCL中)吗?编码通常与文件内容有关,而不是名称;所以这不应该是一个因素。

你应该report this(有一个例子)给作者。

答案 3 :(得分:0)

解压缩时遇到问题。在zip文件中我的应用程序应该读取我有特殊的东欧字符,如šđčćž。 WinRAR或7Zip解压缩得很好,但是使用DNZ库(IonicZip 1.9.1.8)而不是š我得到了μ。

我尝试了15个不同的encondings,终于发现给定的zip文件是ibm852。现在,这段代码示例对我有用:

ZipFile zf = new ZipFile(path, System.Text.Encoding.GetEncoding("ibm852"));
zf.ExtractAll(loc, ExtractExistingFileAction.OverwriteSilently);

设置AlternateEncoding属性,如下面的代码片段对我没有帮助:

using (ZipFile zz = ZipFile.Read(path))
{
    zz.AlternateEncodingUsage = ZipOption.Always;
    zz.AlternateEncoding = System.Text.Encoding.GetEncoding("ibm852");
    zz.ExtractAll(loc, ExtractExistingFileAction.OverwriteSilently);
}

我没时间调查原因,可能你必须在调用构造函数时设置编码,因为我没有在Read方法中找到编码参数。