我需要找出我在某个目录中找到的文件是UTF8编码的ANSI编码,以便在以后我决定的其他内容中更改编码。我的问题是..如何判断文件是UTF8还是ANSI编码?这两种编码实际上都在我的文件中。
答案 0 :(得分:13)
没有可靠的方法(因为文件可能只是随机二进制文件),但Windows记事本软件完成的过程详见Micheal S Kaplan的博客:
http://www.siao2.com/2007/04/22/2239345.aspx
- 检查前两个字节; 1.如果有UTF-16 LE BOM,则将其作为“Unicode”文件处理(并加载); 2.如果存在UTF-16 BE BOM,则将其作为“Unicode(Big Endian)”文件处理(并加载); 3.如果前两个字节看起来像是UTF-8 BOM的开头,那么检查下一个字节,如果我们有一个UTF-8 BOM,那么将其作为“UTF-8”文件处理(并加载);
- 检查IsTextUnicode以查看该功能是否认为它是无BOM的UTF-16 LE,如果是,则将其作为“Unicode”文件处理(并加载);
- 使用1998年的原始RFC 2279定义检查它是否为UTF-8,然后将其作为“UTF-8”文件处理(并加载);
- 使用本机的默认系统代码页假设ANSI文件。
醇>现在请注意有一些漏洞 这里,就像第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;
}
}
要查看BOM表,您需要以十六进制视图查看文件。
记事本在状态栏上显示文件编码,但是,如果文件未设置BOM表,则可以估算出来。