搜索
首页后端开发C#.Net教程关于.NET(C#)正确读取中文编码文件的实例教程

首先如果读者对编码或者BOM还不熟悉的话,推荐先读这篇文章:.NET(C#):字符编码(Encoding)和字节顺序标记(BOM)。
中文编码基本可以分成两大类:
1. ANSI编码的扩展集合:比如GBK, GB2312, GB18030等,这类编码都不存在BOM(一些更新的标准中文编码,比如GB18030和GBK编码,都向后兼容GB2312编码)。
2. Unicode编码集合:比如UTF-8, UTF-16, UTF-32等。这类编码可以有BOM,也可以不加BOM。
3. 部分Unicode编码还存在具体字节次序问题(Endianess),就是所谓的Little endian和Big endian之分,不同此节次序对于不同的BOM,比如UTF16,不过UTF8不存在字节次序问题。

OK,了解了基本知识后,让我们回到主题,该如何正确打开中文文本文件。第一个需要确认的信息是:你的Unicode编码文件是否包含BOM?

如果包含BOM的话,那么一切好说!因为如果我们发现了BOM,我们就知道他的具体编码了。如果没有发现BOM,那就不是Unicode,我们用系统默认的ANSI扩展中文编码集打开文本文件就OK了。
而如果Unicode编码没有BOM的话(显然,你不能保证用户给你的所有Unicode文件都是有BOM的),那么你要手动从原始字节中判断他是GBK?还是UTF8?还是其他编码?。这个就需要具体的编码觉察算法了(可以google “charset|encoding detection”), 当然编码觉察算法不一定会100%准确,正是因为这点,Windows记事本会有Bush hid the facts bug。在Chrome浏览网页时,也会遇到乱码的情况的。个人感觉,Notepad++的编码觉察做的还是很准确的。
编码觉察算法有很多,比如这个工程:https://code.google.com/p/ude

 
如果Unicode都带BOM的话,则就不需要第三方类库了。不过也有一些需要说明的地方。

问题就是.NET中读取文本方法(File类和StreamReader)默认是以UTF8编码来读取的,因此此类GBK的文本文件直接用.NET打开(不指定编码的话)结果肯定是乱码!

首先这里最有效地解决方案是使用系统默认的ANSI扩展编码,也就是系统默认的非Unicode编码来读取文本,参考代码:

//输出系统默认非Unicode编码Console.WriteLine(Encoding.Default.EncodingName);//使用系统默认非Unicode编码来打开文件var fileContent = File.ReadAllText("C:\test.txt", Encoding.Default);

在简体中文的Windows系统下应该输出:

简体中文(GB2312)14b8d1cdd206e5cbcfed886eb0f25e83...

而且使用这个方法其实是不限于简体中文的。

当然也可以手动去指定一个编码,比如就是GBK编码,但是如果用指定的GBK编码去打开一个Unicode文件,文件还会打开成功吗?答案是仍然成功。原因是.NET在打开文件时默认会自动觉察BOM然后用根据BOM得到的编码去打开文件,如果没有BOM再用用户指定的编码区打开文件,如果用户没有指定编码,则使用UTF8编码。

这个”自动觉察BOM“的参数可以在StreamReader中构造函数中设置,对应detectEncodingFromByteOrderMarks参数。

但是在File类的相应方法中无法设置。(比如:File.ReadAllText)。

比如下面代码,分别用:

GB2312编码,自动觉察BOM 来读取GB2312文本

GB2312编码,自动觉察BOM 来读取Unicode文本

GB2312编码,不觉察BOM 来读取Unicode文本

static void Main(){    var gb2312 = Encoding.GetEncoding("GB2312");    //用GB2312编码,自动觉察BOM 来读取GB2312文本    ReadFile("gbk.txt", gb2312, true);    //用GB2312编码,自动觉察BOM 来读取Unicode文本    ReadFile("unicode.txt", gb2312, true);    //用GB2312编码,不觉察BOM 来读取Unicode文本    ReadFile("unicode.txt", gb2312, false);}//通过StreamReader读取文本 static void ReadFile(string path, Encoding enc, bool detectEncodingFromByteOrderMarks){    StreamReader sr;    using (sr = new StreamReader(path, enc, detectEncodingFromByteOrderMarks))    {        Console.WriteLine(sr.ReadToEnd());    }}

输出:

a刘a刘???

第三行是乱码。

看到上面,使用GB2312编码去打开Unicode文件也会成功的。因为“自动觉察BOM”参数为True,所以当发现该文件有BOM,.NET会通过BOM觉察到是Unicode文件,然后用Unicode去打开文件的。当然如果没有BOM,会使用指定的编码参数去打开文件。对于GB2312编码的文本,显然是没有BOM的,所以必须指定GB2312编码,否则.NET会用默认的UTF8编码去解析文件,是无法读取结果的。第三行出现乱码则是由于“自动觉察BOM”为False,.NET会直接用指定的GB2312编码去读取一个有BOM的Unicode编码文本文件,显然无法成功的。

当然还可以自己判断BOM,如果没有BOM的话,指定一个缺省编码去打开文本。我在以前一篇文章中写到过(.NET(C#):从文件中觉察编码)。

代码:

static void Main(){    PrintText("gb2312.txt");    PrintText("unicode.txt");}//根据文件自动觉察编码并输出内容static void PrintText(string path){    var enc = GetEncoding(path, Encoding.GetEncoding("GB2312"));    using (var sr = new StreamReader(path, enc))    {        Console.WriteLine(sr.ReadToEnd());    }}/// <summary>/// 根据文件尝试返回字符编码/// </summary>/// <param name="file">文件路径</param>/// <param name="defEnc">没有BOM返回的默认编码</param>/// <returns>如果文件无法读取,返回null。否则,返回根据BOM判断的编码或者缺省编码(没有BOM)。</returns>static Encoding GetEncoding(string file, Encoding defEnc){    using (var stream = File.OpenRead(file))    {        //判断流可读?        if (!stream.CanRead)            return null;        //字节数组存储BOM        var bom = new byte[4];        //实际读入的长度        int readc;        readc = stream.Read(bom, 0, 4);        if (readc >= 2)        {            if (readc >= 4)            {                //UTF32,Big-Endian                if (CheckBytes(bom, 4, 0x00, 0x00, 0xFE, 0xFF))                    return new UTF32Encoding(true, true);                //UTF32,Little-Endian                if (CheckBytes(bom, 4, 0xFF, 0xFE, 0x00, 0x00))                    return new UTF32Encoding(false, true);            }            //UTF8            if (readc >= 3 && CheckBytes(bom, 3, 0xEF, 0xBB, 0xBF))                return new UTF8Encoding(true);            //UTF16,Big-Endian            if (CheckBytes(bom, 2, 0xFE, 0xFF))                return new UnicodeEncoding(true, true);            //UTF16,Little-Endian            if (CheckBytes(bom, 2, 0xFF, 0xFE))                return new UnicodeEncoding(false, true);        }        return defEnc;    }}//辅助函数,判断字节中的值static bool CheckBytes(byte[] bytes, int count, params int[] values){    for (int i = 0; i < count; i++)        if (bytes[i] != values[i])            return false;    return true;}

上面代码,对于Unicode文本,GetEncoding方法会返回UTF16编码(更具体:还会根据BOM返回Big或者Little-Endian的UTF16编码),而没有BOM的文件则会返回缺省值GB2312编码。

Related Posts:

.NET(C#):从文件中觉察编码

.NET(C#):字符编码(Encoding)和字节顺序标记(BOM)

.NET(C#):使用System.Text.Decoder类来处理“流文本”

.NET(C#):浅谈程序集清单资源和RESX资源

以上是关于.NET(C#)正确读取中文编码文件的实例教程的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
C#和.NET运行时:它们如何一起工作C#和.NET运行时:它们如何一起工作Apr 19, 2025 am 12:04 AM

C#和.NET运行时紧密合作,赋予开发者高效、强大且跨平台的开发能力。1)C#是一种类型安全且面向对象的编程语言,旨在与.NET框架无缝集成。2).NET运行时管理C#代码的执行,提供垃圾回收、类型安全等服务,确保高效和跨平台运行。

C#.NET开发:入门的初学者指南C#.NET开发:入门的初学者指南Apr 18, 2025 am 12:17 AM

要开始C#.NET开发,你需要:1.了解C#的基础知识和.NET框架的核心概念;2.掌握变量、数据类型、控制结构、函数和类的基本概念;3.学习C#的高级特性,如LINQ和异步编程;4.熟悉常见错误的调试技巧和性能优化方法。通过这些步骤,你可以逐步深入C#.NET的世界,并编写高效的应用程序。

c#和.net:了解两者之间的关系c#和.net:了解两者之间的关系Apr 17, 2025 am 12:07 AM

C#和.NET的关系是密不可分的,但它们不是一回事。C#是一门编程语言,而.NET是一个开发平台。C#用于编写代码,编译成.NET的中间语言(IL),由.NET运行时(CLR)执行。

c#.net的持续相关性:查看当前用法c#.net的持续相关性:查看当前用法Apr 16, 2025 am 12:07 AM

C#.NET依然重要,因为它提供了强大的工具和库,支持多种应用开发。1)C#结合.NET框架,使开发高效便捷。2)C#的类型安全和垃圾回收机制增强了其优势。3).NET提供跨平台运行环境和丰富的API,提升了开发灵活性。

从网络到桌面:C#.NET的多功能性从网络到桌面:C#.NET的多功能性Apr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C#.NET与未来:适应新技术C#.NET与未来:适应新技术Apr 14, 2025 am 12:06 AM

C#和.NET通过不断的更新和优化,适应了新兴技术的需求。1)C#9.0和.NET5引入了记录类型和性能优化。2).NETCore增强了云原生和容器化支持。3)ASP.NETCore与现代Web技术集成。4)ML.NET支持机器学习和人工智能。5)异步编程和最佳实践提升了性能。

c#.net适合您吗?评估其适用性c#.net适合您吗?评估其适用性Apr 13, 2025 am 12:03 AM

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

.NET中的C#代码:探索编程过程.NET中的C#代码:探索编程过程Apr 12, 2025 am 12:02 AM

C#在.NET中的编程过程包括以下步骤:1)编写C#代码,2)编译为中间语言(IL),3)由.NET运行时(CLR)执行。C#在.NET中的优势在于其现代化语法、强大的类型系统和与.NET框架的紧密集成,适用于从桌面应用到Web服务的各种开发场景。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。