2014-09-01 43 views
1

我有一个byte []数组,大多只使用阵列的部分,而其余的都是0×00。在这种情况下,我怎样才能得到所需的数组元素,而不是整个数组?我有一个int rxlen,它将是数组中实际元素的长度。我怎样才能获得阵列的一部分,从一个byte []数组

实施例:

byte[] framessent = {0xff, 0x53, 0x7e, 0x80, 0x00, 0x07, 0x60, 0x96, 0x2d, 0x00, 0x00.....} 
byte[] framereceived = {0xff, 0x53, 0x7e, 0x80, 0x00, 0x07, 0x60, 0x96, 0x2d, 0x00, 0x00.....} 

framesent通常为150个字节,这是我的控制,但framereceived是300。我想简单地比较framesent之间的数组元素(有效数据)和framereceived而不是后面的0x00。

我尝试使用Buffer.BlockCopy和Array.Copy如下但是我还是整个阵列,而不是那些我所需要的。

Buffer.BlockCopy(RxBuffer, 0, framereceived, 0, rxlen); 
+0

你就不能使用'.Skip()'(如果需要的话)和'。取()'?这可能不是最好的表现,但我认为它会很容易地完成这项工作,尤其是在你提到的数量方面。 – Maarten 2014-09-01 07:23:45

回答

0

使用一些扩展方法,你可以从原来的阵列得到rxlen如下:

var newArray = framereceived.Take(rxlen).ToArray(); 
0

我大概有你所需要的(道歉,如果我错了)的想法。 如果你需要采取的framereceived的元素0x00,使用Linq:

byte[] validbytes = framereceived.Where(frame => frame != 0x00).ToArray();

如果您需要在两个阵列之间的数据进行比较,并获得唯一包含在这两个元素阵列中的LINQ可以做到这一点,以及(我的方法可能不是有效的):

byte[] validbytes = framereceived.Where(frame => framessent.Contains(frame)).ToArray();

如果你需要从特定文件的特定指数采取字节ngth,请使用.Skip().Take()

0

如果在几个块,你的数据到达的可能性,这样做检查可能会更加复杂一点,其实。

首先,我不会用一个数组来存储输入数据,而是在一个FIFO排队它(即Queue<byte>)。这意味着你的接收事件处理程序看起来是这样的:

// this is the byte "producer" part 
private readonly Queue<byte> _inputQueue = new Queue<byte>(); 
void OnDataReceived(byte[] data) 
{ 
    foreach (var b in data) 
     _inputQueue.Enqueue(b); 

    ConsumeData(); 
} 

然后就“消费”的输入数据,而你的情况意味着你会被它比较固定大小的数组,是这样的:

void ConsumeData() 
{ 
    if (_inputQueue.Count < framessent.Length) 
     return; 

    int index = 0; 
    foreach (var item in _inputQueue) 
    { 
     // item doesn't match? 
     if (item != framessent[index++]) 
     { 
      // data doesn't match 
      OnFailed(); 
      return; 
     } 

     // reached the end of the array? 
     if (index >= _inputQueue.Length) 
     { 
      // data matches 
      OnSuccess(); 
      return; 
     } 
} 

你需要问以下问题是:如果数据确实不匹配会发生什么(例如字节不匹配的一个)。你是做什么?跳过一个字节和重试可能是做的最明智的事情,这意味着ConsumeData方法可能会被改写看起来是这样的:

void ConsumeData() 
{ 
    while (_inputQueue.Count < framessent.Length) 
    { 
     int index = 0; 
     bool success = false; 
     foreach (var item in _inputQueue) 
     { 
      // item doesn't match? 
      if (item != framessent[index++]) 
      { 
       // data doesn't match 
       success = false; 
       break; 
      } 

      // reached the end of the array? 
      if (index >= _inputQueue.Length) 
      { 
       // data matches 
       success = true; 
       break; 
      } 
     } 

     if (success) 
     { 
      OnSuccess(); 
      return; 
     } 
     else 
     { 
      // remove first byte and retry 
      _inputQueue.Dequeue(); 
     } 
    } 
} 

你也将需要采取超时考虑。如果您的ConsumeData方法在一段时间内没有被调用,那就是超时,并且操作应该失败。

相关问题