C#通过编码在字符和字节之间的转换

来源:互联网 发布:椒江法院拍卖网 淘宝 编辑:程序博客网 时间:2024/06/10 00:37

    在平时开发中,时常我们需要将字符串保存到一个文件中,或者通过网络来传输;在CLR中为方便在运行时操作字符串所有都是由16位Unicode代码构成的,保存或者传输一系列16位值在效率上显得不够理想(在英文字符中半数都是有零构成的)。
    通常更有效的方法是将16位值编码成一个压缩字节数组,完成后再将字节数据解码回一个16位值数组。利用这种编码技术,一个托管应用程序也能与非Unicode系统创建的字符串进行交互。
    在C#中如果希望使用System.IO.BinaryWrite或者System.IO.StreamWrite类型将一个字符串发送给一个文件或网络流,必须进行编码(encoding),对应如果使用System.IO.BinaryReader或者System.IO.StreamReader类型从一个文件或网络流中读取一个字符串则必须进行解码(decoding)。如果不显示的指定编码方式,所在类型都默认使用UTF-8,比较容易出现编码方面的问题。
    下面针对FCL中最常用的两种编码方式是UTF-8、UTF-16展开一些讨论:
    例1:使用UTF-8对字符进行编码,解码:

执行结果:

执行结果

    在C#中首次请求编码对象时,Encoding类的属性或者GetEncoding会构件一个对象,并返回。如果之前已请求过编码对象,再次使用时会直接返回先前构件好的对象,以减少系统对象数量和垃圾收集堆的压力, 当然也可以创建相关类的实例,构件任何类的实例都会在托管堆中创建对象,影响性能,故推荐调用Encoding的Static属性,或者GetEncoding方法;
    从字节流中读取字符:
    如果通过一个System.Net.Sockets.NetWorkStream读取一个UTF-16编码的字符串,可能首先从流中读取5个字节,再读7个字节。在UTF-16中每个字节由两个字节构成,这样通过调用GetString方法可能会导致数据丢失或者存储错误;
    这时建议从使用Decoder进行解码,调用它的方法时,它会尽可能多的解码字节数组,如果字节数组包含的字节不足已完成一个字符时,Decoder对象内部会维护相关信息,当下一次调用时会将前次的剩余字节加上当前字节再解码,故:需要从一个流中读取字节时,建议使用Decoder对象,以保证对数据块正确解码!

原创粉丝点击