C# 如何从byte[]数组中获取部分数组
我有一个byte[]数组,大多数情况下只使用了数组的一部分,而其余部分是0x00。在这种情况下,如何仅获取所需的数组元素而不获取整个数组?我有一个int rxlen,它是数组中实际元素的长度 例如:C# 如何从byte[]数组中获取部分数组,c#,arrays,byte,C#,Arrays,Byte,我有一个byte[]数组,大多数情况下只使用了数组的一部分,而其余部分是0x00。在这种情况下,如何仅获取所需的数组元素而不获取整个数组?我有一个int rxlen,它是数组中实际元素的长度 例如: byte[] framessent = {0xff, 0x53, 0x7e, 0x80, 0x00, 0x07, 0x60, 0x96, 0x2d, 0x00, 0x00.....} byte[] framereceived = {0xff, 0x53, 0x7e, 0x80, 0x00, 0x0
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);
使用一些扩展方法,可以从原始数组中获取rxlen,如下所示:
var newArray = framereceived.Take(rxlen).ToArray();
如果我错了,我大概知道你需要什么道歉。 如果需要获取framereceived中非0x00的元素,请使用Linq: 字节[]有效字节=framereceived。其中frame=>frame!=0x00.ToArray 如果需要比较两个数组之间的数据并仅获取两个数组中包含的元素,Linq也可以这样做。我的方法可能效率不高: byte[]validbytes=framereceived.Whereframe=>framessent.Containsframe.ToArray
如果您需要从特定长度的特定索引中提取字节,请使用.Skip和.take。如果您的数据可能以多个块的形式到达,那么执行此检查实际上可能会稍微复杂一点 首先,我不会使用数组来存储传入数据,而是将其放入FIFO(即队列)中。这意味着您的接收事件处理程序将类似于:
// 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;
}
}
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();
}
}
}
您还需要考虑超时。如果您的ConsumerData方法在一段时间内未被调用,则这是一个超时,操作应该会失败。您不能使用。如果需要,请跳过它。是否继续?它可能不会提供最好的性能,但我认为它会很容易地完成这项工作,特别是你提到的数量。