我有一个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.....}
framesent通常是150个字节,我有一个控件但framereceived是300.我想简单地比较framesent和framereceived之间的数组元素(有效数据)而不是后面的0x00。
我尝试使用Buffer.BlockCopy和Array.Copy,但我仍然得到整个数组而不是我需要的数组。
Buffer.BlockCopy(RxBuffer, 0, framereceived, 0, rxlen);
答案 0 :(得分:0)
使用某些扩展方法,您可以从原始数组中获取 rxlen ,如下所示:
var newArray = framereceived.Take(rxlen).ToArray();
答案 1 :(得分:0)
我大致知道你需要什么(道歉,如果我错了)。
如果您需要使用不是 framereceived
的{{1}}元素,请使用Linq:
0x00
如果你需要比较两个数组之间的数据并且只获得两个数组中包含的元素,Linq也可以这样做(我的方法可能效率不高):
byte[] validbytes = framereceived.Where(frame => frame != 0x00).ToArray();
如果您需要从特定长度的特定索引中获取字节,请使用byte[] validbytes = framereceived.Where(frame => framessent.Contains(frame)).ToArray();
和.Skip()
。
答案 2 :(得分: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();
}
然后你&#34;消费&#34;传入的数据,在您的情况下意味着您将它与固定大小的数组进行比较,如:
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
方法暂时没有被调用,则超时并且操作失败。