C#中的德语字母和编码

我有一个解压缩function,我使用System.Text.Encoding来确保提取后的文件在提取后保持相同的名称,因为我解压缩的文件通常包含德语字母。
我尝试了不同的东西,比如Encoding.DefaultEncoding.UTF8但没有任何作用äÄéöÖüß.txt被转换为„Ž‚”™á.txt或者在默认情况下它是黑盒子:/

有什么建议?

 using (ZipArchive archive = System.IO.Compression.ZipFile.Open(ZipFile, ZipArchiveMode.Read, System.Text.Encoding.Default)) { foreach (ZipArchiveEntry entry in archive.Entries) { string fullPath = Path.Combine(appPath, entry.FullName); if (String.IsNullOrEmpty(entry.Name)) { Directory.CreateDirectory(fullPath); } else { if (!entry.Name.Equals("Updater.exe")) { entry.ExtractToFile(fullPath,true); } } } } 

试用CodePage 850(对我有用):

 using (ZipArchive archive = System.IO.Compression.ZipFile.Open(ZipFile, ZipArchiveMode.Read, System.Text.Encoding.GetEncoding(850))) { // .... 

下一个评论来自(一个古老的版本)Sharpziplib,它让我朝着正确的方向前进:

  /* Using the codepage 1252 doesn't solve the 8bit ASCII problem :/ any help would be appreciated. // get encoding for latin characters (like ö, ü, ß or ô) static Encoding ecp1252 = Encoding.GetEncoding(1252); */ // private static Encoding _encoding = System.Text.ASCIIEncoding; private static Encoding _encoding = System.Text.Encoding.GetEncoding(850); 

最后一行是我的更改,使其正确读取带有特殊字符的zip文件。

首先,唯一的官方 (不存在…)ZIP格式不允许使用Unicode字符(那么您不能使用除ASCII之外的任何编码)。

也就是说许多工具和库允许您使用不同的编码,但它可能会失败(例如,如果您尝试解码强制 UTF8 / UTF32或任何使用其他编码编码的文件)。

如果文件名以ASCII编码,它将获得系统的代码页:

对于仅包含ASCII字符的条目名称,将设置语言编码标志,并使用当前系统默认代码页对条目名称进行编码。

对于这个主题,你没有对.NET类有如此大的控制权。 但是,如果您没有指定编码,您将获得默认行为(对于ASCII以外的代码,UTF8和ASCII的当前代码页)。 大多数时候它都有效(如果编码和解码都在相同的代码页内完成)。

怎么避免这个? 这并不容易(因为我们缺乏标准),但总结一下:

  • 不要强制编码 (除非您使用已压缩的zip文件然后使用已知编码)。
  • 在大多数情况下,默认行为非常好。
  • 对于具有扩展字符的 ASCII编码ZIP依赖于系统代码页(在两个系统中它必须相同)。
  • 为用户提供一种更改编码的方法 (您无法检查zip实用程序使用的编码,并且没有关于此的标准)。 这意味着不仅要更改编码(UTF8 / UTF16或其他),还要更改代码页(如果它们不匹配)。 GetEncoding函数将为您指定的代码页提供正确的编码器。

我可以给你最好的提示吗? 依赖于默认行为(这很常见),但如果您需要与大多数ZIP兼容(因为每个ZIP可能以不同的方式实现),那么为用户提供一种更改它的方法,不仅用于编码,还用于编码代码页也是。 特别是不要强制它来自德国特定代码页的代码 ,因为它会打破您将要处理的第一个西class牙语/法语/意大利语/荷兰语文件(并且没有它们的公共代码页)。

如果您打开错误编码的文件(而不是代码页),BTW准备好处理各种exception。

为未来的读者编辑(来自评论): CP 850捕获了大多数西欧常见字符,但它不是欧洲的代码页 。 例如,将它与东欧语言或挪威语进行比较。 它与它们不匹配(并且在语言中33-127范围之外的字符非常常见,因为它们不是盒子绘图)。 CP 850(用于Norsk语言)中没有(例如)CP 850(例如)中的某些字符。

让我举个例子来解释一下。 你有一个文件名(来自Trukey),名称为:“GaripDosyaAdı.txt”。 最后一个字符在CP 857(土耳其)上有代码141。 如果您正在使用CP 850,您将获得“而不是”,因为在原始CP 850中它有代码213.我甚至不会提到远东语言(因为即使您是固定代码页也会变得混乱仅限于欧洲)。 这是您无法设置固定代码页的原因,除非您正在编写一个小实用程序供您自己使用。