.NET如何载入未知编码的文本文档(转)
Windows 的 Notepad 可以打开四种不同编码的文本文档,分别是ASNI,UTF-8,Unicode和Unicode big endian。在.NET中载入文本需要指定要其编码,如果没有指定,默认地使用UTF-8编码。有时候打开的编码不正确,就可能出现乱码的情况。那么在程序载入文本时如何确定要载入的文本是哪种编码呢?一种方法是通过确定文档前的三个字节来实现。
UTF8编码的前3个字节为 0xEF, 0xBB, 0xBF
Unicode编码的前2个字节为 0xFF, 0xFE
Unicode big endian编码的前2个字节的编码为 0xFE, 0xFF
如果不是以上任一种情况,就用系统默认的编码(ANSI)来打开。
示例(C#):
using System.IO; using System.Text;
……
public string OpenTextFile(string fileName) { Encoding encoding = null; FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); // 读文件的前个字节 byte[] bs = br.ReadBytes(3); // 将这个字节转换成16进制的字符串 string s = ""; for (int i = 0; i < bs.Length; i++) s += Convert.ToInt32(bs.ToString()).ToString("X"); // 读完之后将流关闭,后面用另一种方法来加载文本 br.Close(); // 确定编码 if (s.Contains("EFBBBF")) encoding = Encoding.UTF8; else if (s.Contains("FFFE")) encoding = Encoding.Unicode; else if (s.Contains("FEFF")) encoding = Encoding.BigEndianUnicode; else encoding = Encoding.Default; // ANSI编码 // 载入文本,以字符串返回 return File.ReadAllText(fileName, this.fileEncoding); }
对上面方法稍稍改进可以提高效率,具体做法就是直接通过字节来判断而非转换成字符串,即:
public string OpenTextFile(string fileName) { Encoding encoding = null; FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); // 读文件的前个字节 byte[] bs = br.ReadBytes(3); // 读完之后将流关闭,后面用另一种方法来加载文本 br.Close(); // 确定编码 if (bs.Length > 0) { if (bs[0] == 0xEF && bs[1] == 0xBB && bs[2] == 0xBF) encoding = Encoding.UTF8; else if (bs[0] == 0xFF && bs[1] == 0xFE) encoding = Encoding.Unicode; else if (bs[0] == 0xFE && bs[1] == 0xFF) encoding = Encoding.BigEndianUnicode; else encoding = Encoding.Default; // ANSI编码 } else encoding = Encoding.Default; // 空文档时的情况 // 载入文本,以字符串返回 return File.ReadAllText(fileName, this.fileEncoding); }