C#中的字节流处理

在我们日常的编码工作中,如果你的工作是和下位机硬件有交互的话,想必对于字节流的处理碰到的概率是很频繁的,那么今天咱们就简单回顾下对于字节流的数据上位机层面该如何去处理它。

字节流是一种数据传输形式,比如我们的蓝牙传输、网络传输、无线传输等到最后都会变成数据的字节流式传输。.

对于我们编程人员来说,最根本的是掌握字节流的传输规则,其实就是协议。比如我和下位机有数据交互传输协议,那么在传输过程中,数据就必须按照双方规定的协议来传输,否则就会出现解析错误的情况。

对于协议,它可能包括帧头,数据报告帧,校验位,帧尾等。数据的传输就是按照这样的规则进行传输的。我们的发送方和接收方也必须按照协议来发送和解析,否则就会出现错误。

对于将数据以数据流的形式利用网络进行传输,那么势必就需要按照商定的协议来组装和拆解对应的字节。

我们可以看看下图,它是在C#中关于各个数据类型所占的字节数。

C#中的字节流处理

 

在C#中处理字节相关的数据流时,主要用到BitConverter 类。

 

具体可以看MSDN的介绍:

https://docs.microsoft.com/zh-cn/dotnet/api/system.bitconverter?view=netframework-4.5

遇到这样需要处理字节流的数据时,我们将其缓存中的数据存储在新开辟的内存空间中(此空间需要实时替换保存数据),通过BitConverter类中的下列方法,就可以取其空间中的数据(根据协议来取)。

C#中的字节流处理

对于字节流,在业务需求比较频繁的时候可能需要使用到状态机来保证存储数据的准确性,状态机之前文件中有介绍到,有需要了解的朋友可以翻过去看看。

具体可以看看下面的小例子。简单介绍其BitConverter类中方法的应用。

   static void Main(string[] args)
   {
       Console.WriteLine("测试");
       
       int age = 29;
       Byte[] bytes = BitConverter.GetBytes(age
       //字节数组   从流中获取的数据
       byte[] tempData = new byte[20];
       double one=BitConverter.ToDouble(tempData,0);
       int two = BitConverter.ToInt32(tempData,8);            
       Console.ReadKey();
   }

在进行对字节数组的处理过程中,需要特别注意大小端的问题。对于某些数据而言,在不同的计算机系统中,其显示的数值是不同的。

由于某些方法的返回值取决于系统体系结构,因此在将字节数据传输到计算机边界之外时请小心:(下面是微软官方的案例介绍)

  • 如果保证发送和接收数据的所有系统具有相同的尾系,则不对数据执行任何操作。
  • 如果发送和接收数据的系统可以具有不同的端序,则始终按特定顺序传输数据。这意味着,在发送或接收字节之前,可能需要反转数组中的字节顺序。
  static void Main(string[] args)
  {
      Console.WriteLine("测试"
      int value = 12345678;
      byte[] bytes = BitConverter.GetBytes(value);
      Console.WriteLine(BitConverter.ToString(bytes)
      if (BitConverter.IsLittleEndian)                          //如果是小端序则反转字节数组
          Array.Reverse(bytes
      Console.WriteLine(BitConverter.ToString(bytes));          
      
      Console.WriteLine(BitConverter.ToString(bytes));
      if (BitConverter.IsLittleEndian)
          Array.Reverse(bytes
      Console.WriteLine(BitConverter.ToString(bytes));
      int result = BitConverter.ToInt32(bytes, 0
      Console.WriteLine("Original value: {0}", value);
      Console.WriteLine("Returned value: {0}", result);
      Console.ReadKey();
  }
  • 如果发送和接收数据的系统可以具有不同的字节序,并且要传输的数据由带符号整数组成,请调用方法将数据转换为网络字节顺序,并调用方法将其转换位接收方所需的顺序。