Sae*_*ani 6 c# linq arrays extract list
我有一个长度为256的缓冲区,它接收来自蓝牙的字节序列.我需要提取的实际数据包是以字节开头和结尾126.我想使用LINQ在缓冲区中提取最新的数据包.
我现在正在做的是检查最后一个索引,126然后向后计数,直到我到达另一个126.还存在一些缺陷,例如,两个相邻的数据包可能导致两个字节126紧挨着.
这是缓冲区的示例:
126 6 0 5 232 125 93 126 126 69 0 0 1 0 2 2 34 6 0 5 232 125 93 126 126 69 0 0 1 0 2 2 34 6 0 5 232 125 93 126 126 69 0 0 1 0 2 2 34 6 0 5 232 125 93 126 126 69 0 0
所以我的信息是:
所以最后我希望有一个包含正确数据包的数组或列表.例如:
126 69 0 0 1 0 2 2 34 6 0 5 232 125 93 126
Run Code Online (Sandbox Code Playgroud)
你能给我一个从缓冲区中提取这个数据包的快速解决方案吗?
这是我到目前为止所尝试的......它失败了,因为它无法真正返回我正在寻找的正确数据包:
var data = ((byte[])msg.Obj).ToList(); //data is the buffer
byte del = 126; //delimeter or start/end byte
var lastIndex = data.LastIndexOf(del);
var startIndex = 0;
List<byte> tos = new List<byte>(); //a new list to store the result (packet)
//try to figure out start index
if(data[lastIndex - 1] != del)
{
for(int i = lastIndex; i > 0; i--)
{
if(data[i] == del)
{
startIndex = i;
}
}
//add the result in another list
for(int i = 0; i <= lastIndex - startIndex; i++)
{
tos.Add(data[i]);
}
string shit = string.Empty;
foreach (var b in tos)
shit += (int)b + ", ";
//print result in a textbox
AddTextToLogTextView(shit + "\r\n");
}
Run Code Online (Sandbox Code Playgroud)
我准备了三种可能的解决方案,从输入缓冲区中取出最后一个数据包:
使用LINQ
public static byte[] GetLastPacketUsingLINQ(byte[] input, byte delimiter)
{
var part = input.Reverse()
.SkipWhile(i => i != delimiter)
.SkipWhile(i => i == delimiter)
.TakeWhile(i => i != delimiter)
.Reverse();
return (new byte[] { delimiter }).Concat(part).Concat(new byte[] { delimiter }).ToArray();
}
Run Code Online (Sandbox Code Playgroud)
使用string.Split
public static byte[] GetLastPacketUsingString(byte[] input, byte delimiter)
{
var encoding = System.Text.Encoding.GetEncoding("iso-8859-1");
string inputString = encoding.GetString(input);
var parts = inputString.Split(new[] { (char)delimiter }, StringSplitOptions.RemoveEmptyEntries);
return encoding.GetBytes((char)delimiter + parts[parts.Length - 2] + (char)delimiter);
}
Run Code Online (Sandbox Code Playgroud)
使用while循环和索引器
public static byte[] GetLastPacketUsingIndexers(byte[] input, byte delimiter)
{
int end = input.Length - 1;
while (input[end--] != delimiter) ;
int start = end - 1;
while (input[start--] != delimiter) ;
var result = new byte[end - start];
Array.Copy(input, start + 1, result, 0, result.Length);
return result;
}
Run Code Online (Sandbox Code Playgroud)
我还进行了一些非常简单的性能测试。结果如下:
LINQ version result:
126 69 0 0 1 0 2 2 34 6 0 5 232 125 93 126
String version result:
126 69 0 0 1 0 2 2 34 6 0 5 232 125 93 126
Indexers version result:
126 69 0 0 1 0 2 2 34 6 0 5 232 125 93 126
LINQ version time: 64ms (106111 ticks)
String version time: 2ms (3422 ticks)
Indexers version time: 1ms (2359 ticks)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这里最简单的也是最好的。
您可能认为 LINQ 是所有问题的答案,但有时手动编写更简单的解决方案比使用 LINQ 方法确实更好。