C#文本编码识别

需要识别文件编码,网上搜索到很多种方式,结果不太满意,经常误将gb2312判定为utf8,然后就想到一种方式:如果某个文件是A编码,那么将其二进制数据按照A编码转换后的内容应当和有源文件内容一致,假设有个文件A.txt是utf8编码,那么读取到的byte,通过encoding.utf8.getstring转换后的结果应该和直接通过utf8格式读取文本得到的结果一致。
在这个基础上,通过ai生成了如下代码:

        private Encoding DetectEncoding(string filePath)
        {
            byte[] bytes = File.ReadAllBytes(filePath);
            string originalContent = null;

            // 首先检查 BOM 标记
            if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
            {
                return Encoding.UTF8;
            }
            if (bytes.Length >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE)
            {
                return Encoding.Unicode;
            }
            if (bytes.Length >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF)
            {
                return Encoding.BigEndianUnicode;
            }

            // 尝试不同的编码
            Encoding[] encodingsToTry = new Encoding[]
            {
                Encoding.UTF8,
                Encoding.GetEncoding("gb2312"),
                Encoding.GetEncoding("gbk"),
                Encoding.Unicode,
                Encoding.BigEndianUnicode,
                Encoding.ASCII
            };

            foreach (var encoding in encodingsToTry)
            {
                try
                {
                    // 使用当前编码解码字节数组
                    string decodedContent = encoding.GetString(bytes);
                    
                    // 检查是否包含替换字符(通常表示解码失败)
                    if (!decodedContent.Contains("�"))
                    {
                        // 将解码后的内容重新编码
                        byte[] reEncodedBytes = encoding.GetBytes(decodedContent);
                        
                        // 比较原始字节数组和重新编码后的字节数组的长度
                        if (Math.Abs(bytes.Length - reEncodedBytes.Length) <= 3) // 允许最多3个字节的差异(考虑BOM标记)
                        {
                            return encoding;
                        }
                    }
                }
                catch
                {
                    // 如果解码失败,继续尝试下一个编码
                    continue;
                }
            }

            // 如果所有编码都无法正确解码,返回系统默认编码
            return Encoding.Default;
        }

C# 中使用gb2312编码需要先注册:
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
实测验证可以正确区分utf8和gb2312

posted @ 2025-02-24 19:35  youdias  阅读(104)  评论(0)    收藏  举报