小编典典

如何检测文本文件的字符编码?

c#

我尝试检测文件中使用了哪种字符编码。

我尝试使用此代码来获取标准编码

public static Encoding GetFileEncoding(string srcFile)
    {
      // *** Use Default of Encoding.Default (Ansi CodePage)
      Encoding enc = Encoding.Default;

      // *** Detect byte order mark if any - otherwise assume default
      byte[] buffer = new byte[5];
      FileStream file = new FileStream(srcFile, FileMode.Open);
      file.Read(buffer, 0, 5);
      file.Close();

      if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
        enc = Encoding.UTF8;
      else if (buffer[0] == 0xfe && buffer[1] == 0xff)
        enc = Encoding.Unicode;
      else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
        enc = Encoding.UTF32;
      else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
        enc = Encoding.UTF7;
      else if (buffer[0] == 0xFE && buffer[1] == 0xFF)      
        // 1201 unicodeFFFE Unicode (Big-Endian)
        enc = Encoding.GetEncoding(1201);      
      else if (buffer[0] == 0xFF && buffer[1] == 0xFE)      
        // 1200 utf-16 Unicode
        enc = Encoding.GetEncoding(1200);


      return enc;
    }

我的前五个字节是60、118、56、46和49。

是否有图表显示哪种编码与前五个字节匹配?


阅读 448

收藏
2020-05-19

共1个答案

小编典典

您不能依赖具有BOM表的文件。UTF-8不需要它。非Unicode编码甚至没有BOM。但是,还有其他方法可以检测编码。

UTF-32

BOM为00 00 FE FF(对于BE)或FF FE 00 00(对于LE)。

但是即使没有BOM,UTF-32仍易于检测。这是因为Unicode代码点范围限制为U + 10FFFF,因此UTF-32单元始终具有模式00 {00-10}
xx xx(对于BE)或xx xx {00-10} 00(对于LE)
。如果数据的长度是4的倍数,并且遵循以下模式之一,则可以放心地假定它是UTF-32。由于面向字节的编码中很少有00个字节,因此误报几乎是不可能的。

美国ASCII

没有物料清单,但您不需要一个。可以通过缺少80-FF范围内的字节来轻松识别ASCII。

UTF-8

BOM是EF BB BF。但是您不能依靠它。许多UTF-8文件没有BOM,特别是如果它们起源于非Windows系统。

但是您可以放心地假设,如果文件验证为UTF-8,则它 就是 UTF-8。误报很少见。

具体来说,假设数据不是ASCII,则2字节序列的误报率仅为3.9%(1920/49152)。对于7字节的序列,它小于1%。对于12个字节的序列,它小于0.1%。对于24字节的序列,它小于百万分之一。

UTF-16

BOM为FE FF(对于BE)或FF FE(对于LE)。请注意,UTF-16LE BOM位于UTF-32LE BOM的开头,因此请首先检查UTF-32。

如果您碰巧有一个主要由ISO-8859-1字符组成的文件,则文件的一半字节为00也将是UTF-16的有力指标。

否则,识别没有BOM的UTF-16的唯一可靠方法是寻找代理对(D [8-B] xx D [CF] xx),但是非BMP字符很少使用,因此无法使这种方法实用。

XML格式

如果您的文件以3C 3F 78 6D 6C字节(即ASCII字符“
<?xml”)开头,则查找encoding=声明。如果存在,请使用该编码。如果不存在,则采用UTF-8,这是默认的XML编码。

如果需要支持EBCDIC,还请寻找等效的序列4C 6F A7 94 93。

通常,如果您的文件格式包含编码声明,请查找该声明,而不要尝试猜测编码。

以上都不是

还有数百种其他编码,需要花费更多的精力进行检测。我建议尝试使用Mozilla的字符集检测器它的.NET端口

合理的默认值

如果您已排除UTF编码,并且没有指向不同编码的编码声明或统计信息检测,请使用ISO-8859-1或密切相关的Windows-1252。(请注意,最新的HTML标准
要求 将“
ISO-8859-1”声明解释为Windows-1252。)是Windows(英语)(以及其他流行语言,如西班牙语,葡萄牙语,德语和法语)的默认代码页,它是UTF-8以外最常遇到的编码。

2020-05-19