我正在尝试使用DotNetZip Library解压缩文件。
该文件包含带有丹麦字符的文件夹和文件(æøåÆØÅ)。
TotalCommander,7Zip,Windows自带的zip都能正确提取文件,但DotNetZip Library会破坏丹麦语。
例如:File_æøåÆØÅ.txt
变为File_æ¢åÆ¥Å.txt
aø
的{}包含¢
。
Ø
的{{1}}包含¥
。
代码:
using (var zipFile = ZipFile.Read(@"File_æøåÆØÅ.zip"))
{
zipFile.ExtractAll(@"File_æøåÆØÅ",
ExtractExistingFileAction.OverwriteSilently);
}
我正在使用默认编码(“da-DK”文化),我尝试过其他编码,如UTF8等。
如何解压缩包含丹麦字符文件名的文件?
答案 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”中的一个错误 - 您尝试过SharpZipLib或ZipPackage(在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方法中找到编码参数。