【问题标题】:Is it possible to detect text file encoding of two possible?是否可以检测两种可能的文本文件编码?
【发布时间】:2010-08-27 12:26:47
【问题描述】:

我读过How can I detect the encoding/codepage of a text file 无法检测编码。但是是否可以检测编码是否是允许的两种编码之一?

例如,我允许用户将 Unicode UTF-8iso-8859-2 用于他们的 csv 文件。是否可以检测是前者还是后者?

【问题讨论】:

    标签: c# .net character-encoding


    【解决方案1】:

    例如我允许用户使用 Unicode UTF-8 和 iso-8859-2 .csv 文件。是否可以检测 是前者还是后者?

    不可能达到 100% 的准确度,因为例如,字节 C3 B1 是 ISO-8859-2 中“Ăą”的等效表示,就像 UTF-8 中“ñ”一样。事实上,因为 ISO-8859-2 为所有 256 个可能的字节分配了一个字符,所以 每个 UTF-8 字符串也是一个有效的 ISO-8859-2 字符串(如果不是 ASCII,则表示不同的字符)。

    然而,反之则不成立。 UTF-8 对哪些序列有效有严格的规定。超过 99% 的可能 8 字节序列不是有效的 UTF-8。而且您的 CSV 文件可能比这长得多。因此,如果您满足以下条件,您可以获得良好的准确性:

    1. 执行 UTF-8 有效性检查。如果通过,则假定数据为 UTF-8。
    2. 否则,假定它是 ISO-8859-2。

    但是有可能检测到 编码是否是两个之一 允许吗?

    UTF-32(字节顺序)、UTF-8 和 CESU-8 可以通过验证可靠地检测到。 UTF-16 可以通过 BOM 的存在来检测(但不能通过验证来检测,因为偶数长度字节序列成为无效 UTF-16 的唯一方法是使用不成对的代理)。

    如果您至少有一个“可检测”编码,那么您可以检查可检测编码,并使用不可检测编码作为后备。

    如果这两种编码都“无法检测”,例如 ISO-8859-1 和 ISO-8859-2,那就更难了。您可以尝试使用 chardet 之类的统计方法。

    【讨论】:

    • 如何“执行 UTF-8 有效性检查”?
    • 如果数据是无效的UTF-8,那么Encoding.GetString会抛出ArgumentException。
    【解决方案2】:

    由于无法检测编码,即使将其限制为两种可能的编码,您仍然无法检测到它。

    我唯一能想到的是,您可以尝试使用两种可能的编码之一对其进行编码,但是您必须检查它是否正确。这将涉及对文本的解析,即便如此,您也无法 100% 确定它是否正确。

    【讨论】:

      【解决方案3】:

      这两种编码对于所有八位字节

      因此,您需要查看 >= 128 的八位字节才能做出决定。由于在 UTF-8 八位字节 >= 128 总是成组出现(对于较长序列上的 2 个八位字节来编码单个代码点),因此三个八位字节序列 {=128,

      如果文件不包含或仅包含很少的 ASCII 八位字节(即

      使用一些依赖启发式的元数据(就像 XML 的声明一样)通常更可靠,因为可能有人向您发送了 ISO-8859-3。

      【讨论】:

        【解决方案4】:

        如果您使用 StreamReader,则会有一个重载,如果可能,它将检测编码 (BOM),但如果检测失败,则默认为 UTF8。

        我建议您使用两个选项(UTF8 或 Current),如果用户选择您使用的 Current

        var encoding = Encoding.GetEncoding(
              CultureInfo.CurrentCulture.TextInfo.OEMCodePage);
        var reader = new StreamReader(encoding);
        

        这最有希望是正确的编码。

        【讨论】:

        • CultureInfo 是关于环境程序正在运行。在我的情况下,文件是在外部环境中创建的。
        【解决方案5】:

        查看我对链接问题的(最近)回答:How can I detect the encoding/codepage of a text file

        这个类会检查文件是否可能是UTF-8,然后它会尝试猜测它是否可能

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多