字符编码及在.NET平台的使用.docx_第1页
字符编码及在.NET平台的使用.docx_第2页
字符编码及在.NET平台的使用.docx_第3页
字符编码及在.NET平台的使用.docx_第4页
字符编码及在.NET平台的使用.docx_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

引:金旭亮csdn博客 /bitfan漫谈.NET开发中的字符串编码说明:在.NET 4.0面向对象编程漫谈基础篇13.2.1序列化与流中,向大家介绍了如何向流中序列化一个对象。本篇扩充阅读将向读者介绍将字符串对象的序列化,这里面的关键是字符串应该如何编码和解码为二进制数值,从而可以把它们保存到文件流(FileStream)中,或者通过网络流(NetworkStream)将它们远程发送到另一台计算机上。抱怨一下: 使用CSDN的在线编辑器写文章是一个让人望而生畏的工作,当提交文档时,CSDN Web服务器经常报告“内部错误”,所以文章排版不好,诸位见谅。博客园的系统稳定些,读者可以访问/bitfan/archive/2010/11/25/1887590.html看到排版好一点的同样文章。= 1引子在实际开发中,经常需要将一些字符串写入到文本文件中,或者从文本文件中读入字符串,在.NET应用程序中,通常使用StreamReader或StreamWriter两个类完成这一工作,比如以下代码将fileContent字串写入到FileName文件中:staticvoidWriteFileUseStreamWriter(StringfileContent,StringFileName)using(StreamWriterwriter=newStreamWriter(FileName)writer.Write(fileContent);如果你使用.NET基类库中相关类(比如StreamReader或下面用到的File类)去读取这个文件,你会发现一切如你所愿地正常运转:WriteFileUseStreamWriter(中国ab,test.txt);Console.WriteLine(File.ReadAllText(test.txt);/输出:“中国ab” 由于多数情况下我们都工作在中文Windows下,而且往往都是某个.NET程序写,另一个.NET程序读,所以,不少.NET程序员可能都没注意到这其中其实存在着一个字符编码的问题,在特定的场合下,这一问题会给我们带来麻烦。请看图1:图1记事本支持的编码方式默认情况下,Windows记事本以ANSI编码方式保存文件。如图1所示,如果文本内容为“中国ab”,记事本将其以ASNI方式保存为“test.txt”,则以下代码将“罢工”了(参看图2):Console.WriteLine(File.ReadAllText(test.txt);图2汉字将显示为乱码如图2所示,File.ReadAllText方法打开“test.txt”文件时,会发现英文字符可以正常显示,但中文将显示为乱码。2了解字符的编码我们可以做个试验,使用记事本将“中国ab”这个中英混杂的字符串以不同编码方式保存为多个“.txt”文件,然后直接查看其二进制内容:图3比对字符编码图3展示了“中国ab”按四种编码方式(ANSI、UTF8、Unicode、Unicode Big Endian)得到的不同二进制数据。以英文字符“a”为例,ANSI和UTF8得到的数值都是“61”,但Unicode将它扩充为2个字节16位的二进制(“61 00”和“00 61”),所以我们又将这种编码方式称为UTF-16。 UTF-16又可以细分为2种编码方式:Big Endian方式与Little_Edian方式,这两者的唯一区别在于字节排列顺序刚好相反,Little_Edian方式将“a”编码为“61 00”,而Big Endian方式则编码为“00 61”。现在看看中文字符,“中国”两个汉字,ANSI编码为“D6 D0 B9 FA”,4个字节,一个汉字占两个字节,而UTF8则编码为“E4 B8 AD E5 9B BD”,6个字节,一个汉字占3个字节!这说明UTF8是一种“变长”的编码,可能使用14个字节来表示某个字符。另外,我们看到UTF8和Unicode编码(不管是Big Endian还是Little Endian)前面都有几个标记字符,这些字符放在文本文件的开头,称为“BOM(Byte Order Mark,字节顺序标记)”指明了文本的编码方式,以下是.NET程序中常见的字符编码方式的BOM值:编码BOM值UTF-8EF BB BFUTF-16big endianFE FFUTF-16little endianFF FEUTF-32big endian00 00 FE FFUTF-32little endianFF FE 00 00了解了上述基础知识,我们就可以依据BOM值自动检测字符串的编码方式,从而正确从二进制数据流中解码,以下代码检测文本二进制数据是否采用UTF8编码:/打开文件读取二进制数据byteFileContents=File.ReadAllBytes(FilePath);intfilelength=FileContents.Length;/检测BOMif(FileContents0=0xef&FileContents1=0xbb&FileContents2=0xbf)/按UTF8解码字符串,注意要排除掉BOM占用的3个字节。Stringcontent=Encoding.UTF8.GetString( FileContents,3,filelength-3);Console.WriteLine(content);其他的编码方式都可以“依样画葫芦”。3详解.NET基类库中与字符编码相关的类前述代码中的Encoding类是.NET实现字符编码解码的核心类型。图4展示了它的属性:图4 Encoding类型如图4所示,Encoding类型提供了UTF8、Unicode等编码和解码器,调用它的Get系列方法完成编码和解码工作,以下为示例代码:/编码bytebytes=Encoding.UTF8.GetBytes(中国ab);foreach(bytevalueinbytes)Console.Write(0,value.ToString(x);/转化为16进制Console.WriteLine();/解码charchars=Encoding.UTF8.GetChars(bytes);foreach(charchinchars)Console.Write(0,ch);运行结果如下:图5 编码和解码需要注意的是上述二进制值不包括BOM。事实上,.NET中的StreamWriter默认采用UTF8编码格式编码字符串,但并不将UTF8所对应的BOM值(“EF BB BF”)写入到二进制流中。以下是StreamWriter的一个构造函数声明:publicStreamWriter(stringpath):this(path,false,UTF8NoBOM,0x400)类似地,File.ReadAllText()方法在内部使用UTF8来读取指定文件中的字符串:publicstaticstringReadAllText(stringpath)/returnInternalReadAllText(path,Encoding.UTF8); 由于默认编码方式一致,所以配套使用StreamWriter和File.ReadAllText()方法可以正确地从流中存取字符串。 出于提升代码可维护性考虑,正确的用法应该是明确地指明编码方式:staticvoidWriteFileUseStreamWriterUseUTF8(StringfileContent,StringFileName)using(StreamWriterwriter=newStreamWriter(FileName,false,Encoding.UTF8)writer.Write(fileContent);这时,StreamWriter会在文件开头写入UTF8的BOM标记,从而让其他的应用程序可以很明确地知道本文件中字符串的编码方式。4谈谈有趣的Encoding.Default属性Encoding类中有一个有趣的Default属性,它的类型很奇怪,叫作“DBCSCodePageEncoding”,这个类型在MSDN中是查不到的。“DBCS”代表“double-byte character set(双字节字符集)”,它是与“SBCS(single-byte character set,单字节字符集)”相对应的,SBCS中,所有字符都只占一个字节,所以能表示的字符数有限,但在DBCS中,英文字母占一个字节,汉字等特殊字符占有两个字节,从而扩充了Windows能显示的字符数量。 DBCSCodePageEncoding中的“Code Page”被称为“代码页”,每个代码页定义了特定的编码将如何对应于特定的字符(比如简体和繁体中文就分别定义在不同的代码页中),因此,同样的二进制数值,在不同的代码页中,会代表不同的字符。中文Windows通过使用基于代码页的DBCS编码方式,可以方便地以多种编码方式显示和处理字符串。我们在MSDN中可以查到所有代码页的编号,下面列出了可能比较常用的代码页标识:代码页标识值 .NET中的名字936 gb2312950 big51200 utf-1652936 hz-gb-231254936 GB1803065000 utf-765001 utf-8 .NET应用程序可以通过以下方式获取指定代码页的编码对象:Encodingencode=Encoding.GetEncoding(CodePage);以下代码将按照指定代码页编码字符串,并将其写入到文件中:staticvoidWriteFileUseStreamWriterUseCodePage(StringfileContent,StringFileName,intCodePage)using(StreamWriterwriter=newStreamWriter(FileName,false,Encoding.GetEncoding(CodePage) writer.Write(fileContent); 现在,使用以下代码将按照UTF8编码字符串:WriteFileUseStreamWriterUseCodePage(中国ab,t

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论