我们在zip文件中编码文件时出现问题。 我们使用离子拉链来压缩和解压缩档案。 我们位于丹麦,因此我们经常在文件名中包含æ,ø或å的文件。
当用户使用Windows内置工具压缩文件时,我发现它正在使用IBM437 enconding,当我们在其中包含'ø'/'Ø'的文件时,这只是给出了一些时髦的结果。我修改了以下代码:
public static string IBM437Encode(this string text)
{
return text.Replace('ø', '¢').Replace('Ø', '¥');
}
public static string IBM437Decode(this string text)
{
return text.Replace('¢', 'ø').Replace('¥', 'Ø');
}
这已经运行了一段时间了,一切都很好。
但是,因为它总是一个但是,我们没有尝试用mac osx中的默认工具压缩的文件。 所以现在我们遇到了一个新问题.. 使用æ,ø和å时,编码为UTF-8! 所以如果我知道压缩文件的压缩位置,我可以使用它,但有没有简单的方法来检测或规范化压缩文件中的编码?
答案 0 :(得分:6)
检测编码总是很棘手,但UTF8 has strict bitwise rules about what values are expected in a valid sequence,您可以初始化UTF8Encoding对象in a way that will fail by throwing an exception when these sequences are incorrect:
public static Boolean MatchesUtf8Encoding(Byte[] bytes)
{
UTF8Encoding enc = new UTF8Encoding(false, true);
try { enc.GetString(bytes) }
catch(ArgumentException) { return false; }
return true;
}
如果您在zip中的所有文件名上运行,您可以确定它是否在任何地方失败,在这种情况下,您可以断定名称不会保存为UTF-8。
请注意,除了UTF-8之外,计算机的默认编码(Encoding.Default
,通常是美国和西欧国家的Windows-1252,但根据地区和语言而烦恼地不同)和DOS之间存在恼人的差异你已经遇到的-437编码。
区分它们是非常非常困难的,并且可能需要通过实际检查每个编码超出字节0x80的范围产生正常的重音字符,以及哪些是您通常不会遇到的特殊字符来完成在文件名中。例如,很多DOS-437字符都是用于在DOS中绘制半图形用户界面的框架。
作为参考,这些是DOS-437中的特殊字符(因此字节范围为0x80-0xFF):
80 ÇüéâäàåçêëèïîìÄÅ 90 ÉæÆôöòûùÿÖÜ¢£¥₧ƒ A0 áíóúñѪº¿⌐¬½¼¡«» B0 ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ C0 └┴┬├─┼╞╟╚╔╩╦╠═╬╧ D0 ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ E0 αßΓπΣσµτΦΘΩδ∞φε∩ F0 ≡±≥≤⌠⌡÷≈°∙·√ⁿ²■
在Windows-1252中:
80 €�‚ƒ„…†‡ˆ‰Š‹Œ�Ž� 90 �‘’“”•–—˜™š›œ�žŸ A0 ¡¢£¤¥¦§¨©ª«¬�®¯ B0 °±²³´µ¶·¸¹º»¼½¾¿ C0 ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ D0 ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß E0 àáâãäåæçèéêëìíîï F0 ðñòóôõö÷øùúûüýþÿ
其中一些甚至不可打印,因此更容易。
正如你所看到的,一般来说,DOS-437的大多数重音符号都在0x80-0xA5区域(Beta在0xE1经常在德国用作eszett),而Win-1252几乎全部都是他们在0xC0-0xFF区域。如果你确定这些区域,你可以制作一个扫描机制来评估它看起来倾向于哪种编码,只需计算每个区域的预期范围内外的数量。
请注意,c#中的Char
表示unicode字符,无论它是从字节加载的是什么,unicode字符具有某些分类,您可以通过编程方式查找,以区分正常字母(可能与变音符号)和各种特殊字符类(简单示例:我知道其中一个类是“空白字符”)。可能值得研究该系统来自动确定“正常语言字符”的过程。