gpt4 book ai didi

c# - 使用 LINQ 在字节数组中搜索以特定字节开始/结束的所有子数组

转载 作者:可可西里 更新时间:2023-11-01 08:36:48 25 4
gpt4 key购买 nike

我正在处理一个 COM 端口应用程序,我们有一个定义的可变长度数据包结构,我正在用它与微 Controller 通信。数据包具有用于起始字节和停止字节的定界符。问题是有时读取缓冲区可能包含无关的字符。似乎我总是会得到整个数据包,只是在实际数据之前/之后的一些额外的喋喋不休。所以我有一个缓冲区,每当从 COM 端口接收到新数据时,我都会将数据附加到该缓冲区。搜索此缓冲区以查找任何可能出现的数据包的最佳方法是什么?例如:

假设我的数据包定界符是 0xFF 并且我有一个这样的数组

{ 0x00, 0xFF, 0x02, 0xDA, 0xFF, 0x55, 0xFF, 0x04 }

我如何创建一个函数/LINQ 语句来返回所有以分隔符开始和结束的子数组(几乎就像一个带有通配符的滑动相关因子)?

示例将返回以下 3 个数组:

{0xFF, 0x02, 0xDA, 0xFF}, {0xFF, 0x55, 0xFF}, and
{0xFF, 0x02, 0xDA, 0xFF, 0x55, 0xFF}

最佳答案

虽然 Trystan 的回答在技术上是正确的,但他同时制作了原始数组的大量副本。如果起始数组很大并且有一堆定界符,那么它很快就会变得很大。这种方法通过仅使用原始数组和正在评估的当前段的数组来避免大量内存消耗。

public static List<ArraySegment<byte>> GetSubArrays(this byte[] array, byte delimeter)
{
if (array == null) throw new ArgumentNullException("array");

List<ArraySegment<byte>> retval = new List<ArraySegment<byte>>();

for (int i = 0; i < array.Length; i++)
{
if (array[i] == delimeter)
{
for (int j = i + 1; j < array.Length; j++)
{
if (array[j] == delimeter)
{
retval.Add(new ArraySegment<byte>(array, i + 1, j - i - 1));
}
}
}
}

return retval;
}

可以这样使用:

static void Main(string[] args)
{
byte[] arr = new byte[] { 0x00, 0xFF, 0x02, 0xDA, 0xFF, 0x55, 0xFF, 0x04 };
List<ArraySegment<byte>> retval = GetSubArrays(arr, 0xFF);

// this also works (looks like LINQ):
//List<ArraySegment<byte>> retval = arr.GetSubArrays(0xFF);

byte[] buffer = new byte[retval.Select(x => x.Count).Max()];
foreach (var x in retval)
{
Buffer.BlockCopy(x.Array, x.Offset, buffer, 0, x.Count);
Console.WriteLine(String.Join(", ", buffer.Take(x.Count).Select(b => b.ToString("X2")).ToArray()));
}


Console.ReadLine();
}

关于c# - 使用 LINQ 在字节数组中搜索以特定字节开始/结束的所有子数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4616885/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com