C#自動識別文件編碼

 

using System;
using System.IO;
using System.Text;

namespace ConsoleApp1
{

    /// <summary> 
    /// 獲取文件的編碼格式 
    /// </summary> 
    public class EncodingType
    {
        /// <summary> 
        /// 給定文件的路徑,讀取文件的二進制數據,判斷文件的編碼類型 
        /// </summary> 
        /// <param name=“FILE_NAME“>文件路徑</param> 
        /// <returns>文件的編碼類型</returns> 
        public static System.Text.Encoding GetType(string filepath)
        {
            FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
            Encoding r = GetType(fs);
            fs.Close();
            return r;
        }

        /// <summary> 
        /// 通過給定的文件流,判斷文件的編碼類型 
        /// </summary> 
        /// <param name=“fs“>文件流</param> 
        /// <returns>文件的編碼類型</returns> 
        public static System.Text.Encoding GetType(FileStream fs)
        {
            Encoding reVal;
            BinaryReader r = new BinaryReader(fs, Encoding.Default);
            int.TryParse(fs.Length.ToString(), out int 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] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) reVal = Encoding.Unicode;
            else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) reVal = Encoding.BigEndianUnicode;
            else reVal = Encoding.GetEncoding("gb2312");
            r.Close();
            return reVal;
        }

        /// <summary> 
        /// 判斷是否是不帶 BOM 的 UTF8 格式 
        /// </summary> 
        /// <param name=“data“></param> 
        /// <returns></returns> 
        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++;
                        }
                        //標記位首位若爲非0 則至少以2個1開始 如:110XXXXX...........1111110X 
                        if (charByteCounter == 1 || charByteCounter > 6)
                        {
                            return false;
                        }
                    }
                }
                else
                {
                    //若是UTF-8 此時第一位必須爲1 
                    if ((curByte & 0xC0) != 0x80)
                    {
                        return false;
                    }
                    charByteCounter--;
                }
            }
            if (charByteCounter > 1)
            {
                throw new Exception("非預期的byte格式");
            }
            return true;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章