C# 判断文本文件的编码

之前网上找了一个,unicode文件的判断不对,效率也不行,就自己重写了一个

        /// <summary>
        /// 获取文件的编码格式
        /// </summary>
        public static Encoding GetEncoding(string file_name)
        {
            FileStream fs = new FileStream(file_name, FileMode.Open, FileAccess.Read);
            Encoding r = GetEncoding(fs);
            fs.Close();
            return r;
        }

        /// <summary>
        /// 通过给定的文件流,判断文件的编码类型
        /// </summary>
        /// <param name="fs">文件流</param>
        /// <returns>文件的编码类型</returns>
        private static Encoding GetEncoding(FileStream fs)
        {
            //文件的字符集在Windows下有两种,一种是ANSI,一种Unicode。
            //对于Unicode,Windows支持了它的三种编码方式,一种是小尾编码(Unicode),一种是大尾编码(BigEndianUnicode),一种是UTF - 8编码。
            //byte[] Unicode = new byte[] { 0xFF, 0xFE };
            //byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF };
            //byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //BOM头

            if (fs.Length < 3)
                return Encoding.Default;

            byte[] bytes = new byte[3];
            fs.Read(bytes, 0, 3);

            Encoding reVal = Encoding.GetEncoding("GB2312");

            if (bytes[0] == 0xFE && bytes[1] == 0xFF)
            {
                reVal = Encoding.BigEndianUnicode;
            }
            else if (bytes[0] == 0xFF && bytes[1] == 0xFE)
            {
                reVal = Encoding.Unicode;
            }
            else
            {
                if (!(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF))
                {
                    fs.Position = 0;
                }
                if (IsUTF8Bytes(fs))
                {
                    if (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
                        reVal = new UTF8Encoding(false);
                    else
                        reVal = Encoding.UTF8;
                }
            }

            return reVal;
        }

        private static byte UTF8_BYTE_MASK = 0b1100_0000;
        private static byte UTF8_BYTE_VALID = 0b1000_0000;
        private static bool IsUTF8Bytes(FileStream fs)
        {
            //BinaryReader r = new BinaryReader(fs);
            byte[] bytes = new byte[1];
            fs.Read(bytes, 0, 1);

            //1字节 0xxxxxxx
            //2字节 110xxxxx 10xxxxxx
            //3字节 1110xxxx 10xxxxxx 10xxxxxx
            //4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
            //5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
            //6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
            while (fs.Read(bytes, 0, 1) > 0)
            {
                if (bytes[0] < 0x80)
                    continue;

                int cnt = 0;
                byte b = bytes[0];
                while ((b & 0b1000_0000) != 0)
                {
                    cnt++;
                    b <<= 1;
                }
                cnt -= 1;

                for (int i = 0; i < cnt; i++)
                {
                    if (fs.Read(bytes, 0, 1) <= 0)
                        return false;
                    if ((bytes[0] & UTF8_BYTE_MASK) != UTF8_BYTE_VALID)
                        return false;
                }
            }

            return true;
        }

测试验证

            encoding = FileUtil.GetEncoding("data\\计划.csv");
            Console.WriteLine(encoding.EncodingName);
            encoding = FileUtil.GetEncoding("data\\计划2.csv");
            Console.WriteLine(encoding.EncodingName + (encoding.GetPreamble().Length == 0 ? "" : " bom"));
            encoding = FileUtil.GetEncoding("data\\计划3.csv");
            Console.WriteLine(encoding.EncodingName + (encoding.GetPreamble().Length == 0 ? "" : " bom"));
            encoding = FileUtil.GetEncoding("data\\计划4.csv");
            Console.WriteLine(encoding.EncodingName);
            encoding = FileUtil.GetEncoding("data\\计划5.csv");
            Console.WriteLine(encoding.EncodingName);

输出:

简体中文(GB2312)
Unicode (UTF-8) bom
Unicode (UTF-8)
Unicode (Big-Endian)
Unicode

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值