代码改变世界

六、网络数据编码与解码

2014-05-23 10:22  xchit  阅读(1354)  评论(0编辑  收藏  举报

  编码:是指将一组字符转换为一个字节序列的过程。

  解码:将一个编码字节序列转换为一组字符的过程。 为什么需要编码和解码 因为通过网络传递的数据必须是字节序列。

  常用编码:ASCII、Unicode、UTF、国标码

  常用编码 ASCII码:

  每个字符均为7位,主要针对英文。

  UNICODE码:每个字符均占两个字节。

  UTF码:通用转换码,主要解决编码容量问题,

  常用有

  (1)UTF-8:用1到4个字节编码一个UNICODE字符

  (2)UTF-16:将每个字符编码为1至2个16位整数组成的序列

  (3)UTF-32:将每个字符编码为一个32位整数 国标码:常用有 GB2312(1980年公布) GB18030(2000年公布)

  Encoding类

  Encoding类位于System.Text命名空间中。常用属性及方法如下:

名称

说明

Default属性

获取系统的当前ANSI代码页的编码

Unicode属性

获取使用 Little-Endian 字节顺序的 UTF-16 格式的编码

UTF8属性

获取UTF-8格式的编码

Convert方法

将字节数组从一种编码转换为另一种编码

GetBytes方法

将一组字符编码为一个字节序列

GetString方法

将一个字节序列解码为一个字符串

GetEncoder方法

获取一个解码器,该解码器将Unicode字符序列转换为已编码的字节序列

GetDecoder方法

获取一个解码器,该解码器将已编码的字节序列转换为字符序列

  

  1.获取所有编码名称及其描述信息

  GetEncodings方法获得包含所有编码的EncodingInfo数组。

  下面的代码可以获取所有编码的名称及其名称描述。

  

 foreach (EncodingInfo ei in Encoding.GetEncodings())
            {
                Encoding en = ei.GetEncoding();
                Console.WriteLine(string.Format("{0,-18}{1}", ei.Name, en.EncodingName));
            }

  2.获取某个指定的编码描述信息

    (1)访问UTF8、ASCII等属性,直接获得其他非Unicode的某个指定字符集的编码实例。

    Encoding ASCIIEncode = Encoding.ASCII;

    (2)利用静态方法GetEndcoing来获取编码实例,

    例如: Encoding GB2312Encoding = Encoding.GetEncoding("GB2312");

    (3)访问HeaderName属性,获取指定编码的名称

    Console.WriteLine(GB2312Encoding. HeaderName);

    (4)访问EncodingName属性,显示指定编码的名称描述                 

    Console.WriteLine(GB2312Encoding.EncodingName);

  3.不同编码之间的转换

    功能:Encoding类的Convert方法可将字节数组从一种编码转换为另一种编码,转换结果类型为byte[] 。

    方法原型: public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding, byte[] bytes)

    参数说明:

      srcEncoding表示源编码格式。

      dstEncoding表示目标编码格式。

      bytes参数指定了待转换的字节数。

      将Unicode字符串转换为UTF8字符串时,可参考以下的步骤进行。

  将Unicode字符串转换为UTF8字符串:

    (1)利用Encoding的UTF8和Unicode属性获取UTF8格式的编码实例utf8和Unicode格式的编码实例unicode,

    例如:

       string unicodeString = "含unicode字符Pi(\u03a0)"; 
            Encoding unicode = Encoding.Unicode; 
            Encoding utf8 = Encoding.UTF8;

 

 

    (2)利用unicode的GetBytes方法将Unicode字符编码为Unicode字节数组,

    例如: 

      byte[] unicodeBytes = unicode.GetBytes(unicodeString);

    (3)利用Encoding的Convert方法将Unicode字节数组转换为UTF8字节数组,

    例如: 

      byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, unicodeBytes);

 

    (4)最后,利用ut8的GetString方法将UTF8字节数组解码为UTF8字符串,

    例如: 

      string utf8String = utf8.GetString(utf8Bytes);

  为什么使用Encoder及Decoder类?

  在网络传输和文件操作中,如果数据量比较大,需要划分为较小的块,此时可能出现一个数据块的末尾是一个不匹配的高代理项,而与其匹配的低代理项则位于下一个数据块中。对于这种情况,直接使用Encoding类的GetBytes方法编写程序就比较繁琐。此时,可以利用Encoder类轻松地解决这个问题。

  Encoder类 Encoder类位于System.Text名称空间下,利用它可以将一组字符转换为一个字节序列。

  (1)获取Encoder实例:利用GetEncoder方法获取实例

    

    //获取ASCII编码的Encoder实例

    Encoder asciiEncoder = Encoding.ASCII.GetEncoder();

    //获取Unicode编码的Encoder实例

    Encoder unicodeEncoder = Encoding.Unicode.GetEncoder();

  (2)GetBytes方法 GetBytes方法将一组字符编码转换为字节序列。

    参数说明:

    

public virtual int GetBytes(

      char[] chars, //要编码的字符数组

      int charIndex //第一个要编码的字符的索引

      int charCount //要编码的字符的数目

      byte[] bytes, //存储编码后的字节序列的字节数组

      int byteIndex: //开始目的字节序列的索引位置

      bool flush //是否在转换后清除编码器的内部状态

    )

  (3)GetByteCount方法 Encoder类提供的GetByteCount方法可计算对字符序列进行编码后所产生的精确字节数,以确定字节数组的长度。

  方法原型:

public abstract int GetByteCount(

    char[] chars, //包含要编码的字符集的字符数组

    int index, //第一个要编码的字符的索引

    int count, //要编码的字符的数目

     bool flush //是否在计算后清空内部缓存状态

  )

  用Decoder类解码的步骤为:首先通过Encoding的GetDecoder方法创建Decoder实例,然后利用实例的GetChars方法将字节序列解码。

  GetChars方法用于将一个字节序列解码为一组字符,并从指定的索引位置开始存储这组字符。该方法返回向chars写入的实际字符数。

  方法原型:

public abstract int GetChars(

    byte[] bytes, //包含要解码的字节序列的字节数组

     int byteIndex, //第一个要解码的字节的索引

    int byteCount, //要解码的字节数

    char[] chars, //包含所产生的字符集的字符数组

    int charIndex //写入所目的字节数组的索引位置

  )

  

  编码/解码DEMO