繁体   English   中英

如何从byte []数组中获取数组的一部分

[英]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();

我大致了解您的需求(如果我错了,我们深表歉意)。 如果需要采用 0x00framereceived元素,请使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM