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

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

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

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

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

它的内容包含一个¢ 。 一个Ø包含一个¥

码:

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

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

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

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

您应该向作者报告此 (带有示例)。

要处理该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文档中描述,特别是在ZipFile.ProvisionalAlternateEncoding属性中。

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

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

并且用于制作zip存档: ZipFile zip = new ZipFile(Encoding.UTF8);

首先使用的覆盖DotNetZip默认编码

 zip.AlternateEncodingUsage = ZipOption.Always; 

是危险的,因为它总是覆盖zip编码,尽管zip实际使用。 我自己用过

 zip.AlternateEncoding = System.Text.Encoding.UTF8; zip.AlternateEncodingUsage = ZipOption.AsNecessary; 

所以在需要时使用utf-8。

但是与代码页讨论有关 – 我已经在dotnetzip本身(我有本地副本)中修复了这个问题,并将默认代码页从“ibm437”更改为“ibm861”。

我使用7-zip和windows压缩工具来创建特殊类型的zip,并在文件名中使用特殊字符’ø’。 基于测试结果,Windows和7-zip使用的默认编码是“ibm861”,而不是大多数文档指定的“ibm437”。

修复可以通过搜索“ibm437”字符串并在dotnetzip本身中替换为“ibm861”来应用。

这里是我提到的有关编码页面的一些内容: http : //www.nudoq.org/#!/Packages/DotNetZip/Ionic.Zip/ZipInputStream/P/ProvisionalAlternateEncoding

解压缩时遇到问题。 在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方法中找到编码参数。