[英]How can I get part of the array from a byte[] array
我有一个byte []数组,大部分仅使用数组的一部分,其余部分为0x00。 在这种情况下,如何仅获取所需的数组元素而不是整个数组? 我有一个int rxlen,它将是数组中实际元素的长度。
例:
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.....}
frameent通常为150字节,我可以控制它,但是framereceived为300字节。我想简单比较一下frameent和framereceived之间的数组元素(有效数据),而不是后面的0x00。
我尝试如下使用Buffer.BlockCopy和Array.Copy,但是我仍然可以得到整个数组,而不是我需要的数组。
Buffer.BlockCopy(RxBuffer, 0, framereceived, 0, rxlen);
使用一些扩展方法,您可以从原始数组中获取rxlen ,如下所示:
var newArray = framereceived.Take(rxlen).ToArray();
我大致了解您的需求(如果我错了,我们深表歉意)。 如果需要采用非 0x00
的framereceived
元素,请使用Linq:
byte[] validbytes = framereceived.Where(frame => frame != 0x00).ToArray();
如果需要比较两个数组之间的数据并仅获取两个数组中包含的元素,Linq也可以做到这一点(我的方法可能无效):
byte[] validbytes = framereceived.Where(frame => framessent.Contains(frame)).ToArray();
如果需要从特定长度的特定索引中获取字节,请使用.Skip()
和.Skip()
.Take()
。
如果您的数据有可能分成几部分到达,那么执行此检查实际上可能会稍微复杂一点。
首先,我不会使用数组来存储传入的数据,而是将其放入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
方法有一段时间没有被调用,则表示超时,操作将失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.