您的位置:首页 > 编程语言 > C#

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

2009-08-17 17:40 323 查看
    在平时开发中,时常我们需要将字符串保存到一个文件中,或者通过网络来传输;在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对字符进行编码,解码:

using System;
using System.Text;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
String s = "Hello Richard!"; //准备编码的字符串
Encoding encodingUTF8 = Encoding.UTF8; //从Encoding派生一个类型进行编码,解码操作
Byte[] encodeBytes = encodingUTF8.GetBytes(s); //将字符串编码
Console.WriteLine("Encoded Bytes:" + BitConverter.ToString(encodeBytes));
String decodedString = encodingUTF8.GetString(encodeBytes);//将字节数组解码
Console.WriteLine("Decoded String:" + decodedString);
Console.ReadLine();
}
}
}


执行结果:



    在C#中首次请求编码对象时,Encoding类的属性或者GetEncoding会构件一个对象,并返回。如果之前已请求过编码对象,再次使用时会直接返回先前构件好的对象,以减少系统对象数量和垃圾收集堆的压力, 当然也可以创建相关类的实例,构件任何类的实例都会在托管堆中创建对象,影响性能,故推荐调用Encoding的Static属性,或者GetEncoding方法;

    从字节流中读取字符:

    如果通过一个System.Net.Sockets.NetWorkStream读取一个UTF-16编码的字符串,可能首先从流中读取5个字节,再读7个字节。在UTF-16中每个字节由两个字节构成,这样通过调用GetString方法可能会导致数据丢失或者存储错误;

    这时建议从使用Decoder进行解码,调用它的方法时,它会尽可能多的解码字节数组,如果字节数组包含的字节不足已完成一个字符时,Decoder对象内部会维护相关信息,当下一次调用时会将前次的剩余字节加上当前字节再解码,故:需要从一个流中读取字节时,建议使用Decoder对象,以保证对数据块正确解码!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息