• 六、网络数据编码与解码


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

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

      常用编码: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

  • 相关阅读:
    Python数据可视化——散点图
    [ffmpeg 扩展第三方库编译系列] 关于 mingw32 下编译libcaca
    独立python环境之virtualenv和virtualenvwrapper
    深入理解maven及应用(一):生命周期和插件
    Android页面事件挂接模拟
    第六课 Struts的视图组件
    wxWidgets笔记_1_linux环境下wxwidgets的安装与配置
    使用 gradle 在编译时动态设置 Android resValue / BuildConfig / Manifes中<meta-data>变量的值
    ubuntu 下安装eclipse &java环境配置
    [Swift]LeetCode695. 岛屿的最大面积 | Max Area of Island
  • 原文地址:https://www.cnblogs.com/xchit/p/socket_6.html
Copyright © 2020-2023  润新知