adpost'sblog

有方向有阶段的努力才能离目标更近,
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

.net 取得 文件的编码

Posted on 2010-05-25 10:08  adpost  阅读(598)  评论(1)    收藏  举报

在.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,至此我们就得到文件的相应编码了。