C#自动获取指定文本文件的编码格式Encoding以及BOM (Byte Order Mark字节顺序标记)

83 篇文章 3 订阅
13 篇文章 1 订阅
本文介绍了如何使用C#来检测文本文件的编码格式,包括通过字节顺序标记(BOM)识别UTF-8、UTF-16和UTF-32等编码,并提供了不依赖BOM的UTF-8编码判断方法。示例代码详细展示了如何读取文件并进行编码判断。
摘要由CSDN通过智能技术生成

我们在读写文本文件(如.txt,.csv,.log等)过程中,如果指定的文本文件编码格式不正常,读写就会出现乱码现象。

这里自动获取编码格式

BOM【字节顺序标记】

BOM(Byte Order Mark),字节顺序标记,出现在文本文件头部,Unicode编码标准中用于标识文件是采用哪种格式的编码。

不同编码的字节顺序标记的表示

编码

表示 (十六进制)

表示 (十进制)

UTF-8

EF BB BF

239 187 191

UTF-16(大端序)

FE FF

254 255

UTF-16(小端序)

FF FE

255 254

UTF-32(大端序)

00 00 FE FF

0 0 254 255

UTF-32(小端序)

FF FE 00 00

255 254 0 0

UTF-7

2B 2F 76和以下的一个字节:[ 38 | 39 | 2B | 2F ]

43 47 118和以下的一个字节:[ 56 | 57 | 43 | 47 ]

en:UTF-1

F7 64 4C

247 100 76

en:UTF-EBCDIC

DD 73 66 73

221 115 102 115

en:Standard Compression Scheme for Unicode

0E FE FF

14 254 255

en:BOCU-1

FB EE 28及可能跟随着FF

251 238 40及可能跟随着255

GB-18030

84 31 95 33

132 49 149 51

C#示例代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AutoGetFileEncoderDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string fileName = @"C:\Users\Administrator\Desktop\test.txt";
            Encoding encoding = GetTextFileEncodingType(fileName);
            Console.WriteLine(encoding.GetType());
            Console.WriteLine($"代码页:【{encoding.CodePage}】,描述【{encoding.EncodingName}】");
            Console.WriteLine($"WindowsCodePage:【{encoding.WindowsCodePage}】,WebName:【{encoding.WebName}】,HeaderName:【{encoding.HeaderName}】,BodyName:【{encoding.BodyName}】");
            Console.ReadLine();
        }

        /// <summary>
        /// 获取文本文件的字符编码类型
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        static Encoding GetTextFileEncodingType(string fileName) 
        {
            Encoding encoding = Encoding.Default;
            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader = new BinaryReader(fileStream, encoding);
            byte[] buffer = binaryReader.ReadBytes((int)fileStream.Length);
            binaryReader.Close();
            fileStream.Close();
            if (buffer.Length >= 3 && buffer[0] == 239 && buffer[1] == 187 && buffer[2] == 191)
            {
                encoding = Encoding.UTF8;
            }
            else if (buffer.Length >= 3 && buffer[0] == 254 && buffer[1] == 255 && buffer[2] == 0)
            {
                encoding = Encoding.BigEndianUnicode;
            }
            else if (buffer.Length >= 3 && buffer[0] == 255 && buffer[1] == 254 && buffer[2] == 65)
            {
                encoding = Encoding.Unicode;
            }
            else if (IsUTF8Bytes(buffer)) 
            {
                encoding = Encoding.UTF8;
            }
            return encoding;
        }

        /// <summary>
        /// 判断是否是不带 BOM 的 UTF8 格式
        /// BOM(Byte Order Mark),字节顺序标记,出现在文本文件头部,Unicode编码标准中用于标识文件是采用哪种格式的编码。
        /// </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;
        }
    }
}

测试运行如图:

C#中修改文件编码格式可以通过以下步骤实现: 1. 使用System.IO命名空间下的File类读取文件的内容。可以使用File.ReadAllText()或者File.ReadAllBytes()方法来读取文件的内容。 2. 通过判断文件内容的编码格式来确定当前文件的编码格式。可以使用System.Text.Encoding类的GetEncoding()方法来判断文件的编码格式。如果是Unicode编码,可以使用Encoding.Unicode属性来表示。 3. 如果需要修改文件的编码格式为UTF-8,可以使用System.Text.Encoding类的GetBytes()方法将文件内容转换为字节数组,并指定目标编码格式为UTF-8。 4. 使用System.IO命名空间下的File类将修改后的字节数组写入文件中。可以使用File.WriteAllBytes()方法来写入字节数组到文件中。 下面是一个示例代码,演示如何在C#中修改文件的编码格式为UTF-8: ``` using System.IO; using System.Text; public class FileEncodingConverter { public static void ConvertFileEncoding(string filePath) { // 读取文件内容 byte[] fileContent = File.ReadAllBytes(filePath); // 判断文件的编码格式 Encoding fileEncoding = GetFileEncoding(fileContent); // 将文件内容转换为UTF-8编码 byte[] utf8Content = Encoding.Convert(fileEncoding, Encoding.UTF8, fileContent); // 将修改后的内容写入文件 File.WriteAllBytes(filePath, utf8Content); } private static Encoding GetFileEncoding(byte[] content) { // 判断文件的编码格式 if (content.Length >= 3 && content == 0xEF && content == 0xBB && content == 0xBF) { // UTF-8 with BOM return Encoding.UTF8; } else if (content.Length >= 2 && content == 0xFF && content == 0xFE) { // UTF-16 Little Endian return Encoding.Unicode; } else if (content.Length >= 2 && content == 0xFE && content == 0xFF) { // UTF-16 Big Endian return Encoding.BigEndianUnicode; } else { // 默认使用系统当前编码 return Encoding.Default; } } } // 调用示例 string filePath = "path/to/your/file.txt"; FileEncodingConverter.ConvertFileEncoding(filePath); ``` 以上代码会将指定文件的编码格式修改为UTF-8,并保存修改后的内容。请确保在使用该代码时传入正确的文件路径。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C#批量替换文档的编码格式](https://download.csdn.net/download/oshizu/5763281)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C# 确定文件编码格式的方法](https://blog.csdn.net/lihongmao5911/article/details/128880240)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值