在.net中打开读取文件内容时,如果不对文件编码进行匹配时经常会把文件内容读成乱码。所以就有了以下的文章。
如何得知这个文件的编码方式?
BOM
这里涉及到一个BOM(Byte Order Mark) 的概念。简单的讲,在Unicode标准中,为了标示文本文件的编码类型,可以在文本文件的开始插入几个特殊的byte,通过这几个特殊的byte,应用程序就可以鉴别文本文件使用的是那种编码了。那几个特殊的byte也被称之为BOM(参考:http://unicode.org/faq/utf_bom.html)
对于Unicode,几种编码的BOM如下:
/// <summary>
/// 文件编码
/// </summary>
private enum fileEncoding {
/// <summary>
/// UTF-8:前3个byte是:EF BB BF
/// </summary>
UTF8,
/// <summary>
/// UTF-16 big-endian:前2个byte是:FE FF
/// </summary>
UTF16BigEndian,
/// <summary>
/// UTF-16 little-endian:前2个byte是:FF FE
/// </summary>
UTF16LittleEndian,
/// <summary>
/// UTF-32 big-endian:前4个byte是:00 00 FE FF
/// </summary>
UTF32BigEndian,
/// <summary>
/// UTF-32 little-endian:前4个byte是:FF FE 00 00
/// </summary>
UTF32LittleEndian,
/// <summary>
/// UTF7:所有的byte转换为十进制都小于127
/// </summary>
UTF7,
/// <summary>
/// 找不到BOM 未知编码
/// </summary>
Unknown
}
判定文件编码方式:
我们知道UNCODE文件相对应的编码后我们就可以读取文件的前几个byte然后判断文件的相应编码:
/// <summary>
/// 通过文件BOM 取得文件编码
/// </summary>
/// <param name="buffer">文件前100个字节</param>
/// <returns></returns>
private fileEncoding FileEncoding(byte[] buffer)
{
bool IsUTF7 = false;
if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
return fileEncoding.UTF8;
if (buffer[0] == 0xfe && buffer[1] == 0xff)
return fileEncoding.UTF16BigEndian;
if (buffer[0] == 0xff && buffer[1] == 0xfe)
return fileEncoding.UTF16LittleEndian;
if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
return fileEncoding.UTF32BigEndian;
if (buffer[0] == 0xff && buffer[1] == 0xfe && buffer[2] == 0 && buffer[3] == 0)
return fileEncoding.UTF32LittleEndian;
for (int i = 0; i < buffer.Length; i++)
{
if (buffer[i] > 127)
{
IsUTF7 = false;
break;
}
}
if (IsUTF7)
return fileEncoding.UTF7;
else
return fileEncoding.Unknown;
}
得到文件的相应编码类型后,我们就可以转换为.net里的 System.Text.Encoding了。
/// <summary>
/// 转换 fileEncoding enum 为 System.Text.Encoding
/// </summary>
/// <param name="fe">自定义 编码 enum</param>
/// <returns></returns>
private Encoding FileEnCoding(fileEncoding fe)
{
Encoding e = Encoding.Default;
switch (fe)
{
case fileEncoding.UTF8:
e = Encoding.UTF8;
break;
case fileEncoding.UTF16BigEndian:
case fileEncoding.UTF16LittleEndian:
e = Encoding.Unicode;
break;
case fileEncoding.UTF32BigEndian:
case fileEncoding.UTF32LittleEndian:
e = Encoding.UTF32;
break;
case fileEncoding.UTF7:
e = Encoding.UTF7;
break;
}
return e;
}
OK,至此我们就得到文件的相应编码了。
浙公网安备 33010602011771号