c# - zip 文件编码 (C#/ionic-zip)

标签 c# encoding zip ionic-zip

我们遇到了 zip 文件中文件编码的问题。 我们正在使用 ionic zip 来压缩和解压缩文件。 我们位于丹麦,因此我们经常有文件名中包含 æ、ø 或 å 的文件。

当用户使用 Windows 内置工具压缩文件时,我发现它使用的是 IBM437 编码,当我们的文件中包含 'ø'/'Ø' 时,这只会给出一些奇怪的结果。我用以下代码解决了这个问题:

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! 因此,如果我知道 zip 的压缩位置,我就可以让它工作,但是有什么简单的方法可以检测或规范化 zip 中的编码吗?

最佳答案

检测编码总是一件棘手的事情,但是 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 区域(0xE1 处的 Beta 在德国通常用作 eszett ),而 Win-1252 几乎所有重音字符都位于区域 0xC0-0xFF。如果您确定了这些区域,您就可以建立一个扫描机制来评估它似乎倾向于哪种编码,只需计算每个区域落入和落入预期范围之外的数量即可。


请注意,c# 中的 Char 代表一个 unicode 字符,无论它是从什么字节加载的,并且 unicode 字符具有特定的分类,您可以通过编程方式查找这些分类以区分它们与普通字母(可能与变音符号)和各种特殊字符类别(简单示例:我知道其中一类是“空白字符”)。可能值得研究该系统以自动确定什么是“正常语言字符”。

关于c# - zip 文件编码 (C#/ionic-zip),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48441051/

相关文章:

c# - 使用 C# 处理字节数组中的 _bstr_t 并返回

c# - 从 Log4Net 日志文件创建 zip 会导致 System.IO.IOException

ios - 如何在swift中解压ftp下载的数据

c# - 通过同一 session 进行 Telegram 客户端更新和 API 请求

python - 阿拉伯语编码-django

php - 如何用PHP解析特殊字符到MySQL?

flutter - 如何在Flutter中直接访问ZIP文件资源(不暂时存储解压后的文件)?

c# - 从字符串中提取多个整数并存储为 int

c# - 在解析期间确定依赖项的目标类型

c# - Visual Studio 2010 中的代码覆盖率测试?如何?