如何找到文件的编码? C#

时间:2010-08-04 09:26:47

标签: c#

我需要找出我在某个目录中找到的文件是UTF8编码的ANSI编码,以便在以后我决定的其他内容中更改编码。我的问题是..如何判断文件是UTF8还是ANSI编码?这两种编码实际上都在我的文件中。

5 个答案:

答案 0 :(得分:13)

没有可靠的方法(因为文件可能只是随机二进制文件),但Windows记事本软件完成的过程详见Micheal S Kaplan的博客:

http://www.siao2.com/2007/04/22/2239345.aspx

  
      
  1. 检查前两个字节;        1.如果有UTF-16 LE BOM,则将其作为“Unicode”文件处理(并加载);        2.如果存在UTF-16 BE BOM,则将其作为“Unicode(Big Endian)”文件处理(并加载);        3.如果前两个字节看起来像是UTF-8 BOM的开头,那么检查下一个字节,如果我们有一个UTF-8 BOM,那么将其作为“UTF-8”文件处理(并加载);
  2.   
  3. 检查IsTextUnicode以查看该功能是否认为它是无BOM的UTF-16 LE,如果是,则将其作为“Unicode”文件处理(并加载);
  4.   
  5. 使用1998年的原始RFC 2279定义检查它是否为UTF-8,然后将其作为“UTF-8”文件处理(并加载);
  6.   
  7. 使用本机的默认系统代码页假设ANSI文件。
  8.         

    现在请注意有一些漏洞   这里,就像第2步那样   没有BOM也没那么好   UTF-16 BE(甚至可能存在错误   在这里,我不确定 - 如果是这样,这是一个错误   在记事本中超越任何bug   IsTextUnicode)。

答案 1 :(得分:4)

http://msdn.microsoft.com/en-us/netframework/aa569610.aspx#Question2

  

没有很好的方法来检测   任意ANSI代码页,尽管有   已经尝试过这样做了   基于某些概率   文本中间的字节序列。   我们不在StreamReader中尝试。一个   XML或HTML等文件格式很少   一种指定字符集的方法   在文件的第一行,所以Web   浏览器,数据库和类   XmlTextReader可以读取这些文件   正确。但许多文本文件没有   建立这种类型的信息   英寸

答案 2 :(得分:2)

Unicode / UTF8 / UnicodeBigEndian被认为是不同的类型。 ANSI被认为与UTF8相同。

public class EncodingType
{
    public static System.Text.Encoding GetType(string FILE_NAME)
    {
        FileStream fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);
        Encoding r = GetType(fs);
        fs.Close();
        return r;
    }

    public static System.Text.Encoding GetType(FileStream fs)
    {
        byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
        byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
        byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //with BOM
        Encoding reVal = Encoding.Default;

        BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default);
        int i;
        int.TryParse(fs.Length.ToString(), out i);
        byte[] ss = r.ReadBytes(i);
        if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
        {
            reVal = Encoding.UTF8;
        }
        else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
        {
            reVal = Encoding.BigEndianUnicode;
        }
        else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
        {
            reVal = Encoding.Unicode;
        }
        r.Close();
        return reVal;

    }

    private static bool IsUTF8Bytes(byte[] data)
    {
        int charByteCounter = 1;  
        byte curByte; 
        for (int i = 0; i < data.Length; i++)
        {
            curByte = data[i];
            if (charByteCounter == 1)
            {
                if (curByte >= 0x80)
                {
                    while (((curByte <<= 1) & 0x80) != 0)
                    {
                        charByteCounter++;
                    }
                     
                    if (charByteCounter == 1 || charByteCounter > 6)
                    {
                        return false;
                    }
                }
            }
            else
            {
                if ((curByte & 0xC0) != 0x80)
                {
                    return false;
                }
                charByteCounter--;
            }
        }
        if (charByteCounter > 1)
        {
            throw new Exception("Error byte format");
        }
        return true;
    }

}

答案 3 :(得分:0)

请参阅这两个代码项目文章 - 仅从文件内容中找出文件编码并非易事:

答案 4 :(得分:0)

   public static System.Text.Encoding GetEncoding(string filepath, Encoding defaultEncoding)
    {
        // will fall to defaultEncoding if file does not have BOM

        using (var reader = new StreamReader(filepath, defaultEncoding, true))
        {
            reader.Peek(); //need it
            return reader.CurrentEncoding;
        }
    }

选中Byte Order Mark (BOM)

要查看BOM表,您需要以十六进制视图查看文件。

记事本在状态栏上显示文件编码,但是,如果文件未设置BOM表,则可以估算出来。