我有一个大字节数组。数组中有多个包。目前还不清楚有多少个包。
Package Structure =>报头(0xAA 0xFE) +长度(2字节)+数据(长度字节)+校验和(2字节)
我想把大数组中的包分成单独的数组。下面的算法就是这样做的。有可能用LINQ做到这一点吗?
我想学习的是如何用LINQ控制复杂的结构。
如果可以用LINQ完成,你能帮忙吗?从现在开始谢谢你。
List<byte[]> allPacket = new List<byte[]>();
public void LogReadBuffer(byte[] buffer)
{
try
{
for(long i = 0; i < buffer.Length;)
{
if(buffer[i] == (char)0xAA && buffer[i+1] == 0xFE && Step == 0)
{
Lenght = (short)(
((byte)buffer[i + 2] << 8) +
((byte)buffer[i + 3] << 0));
packet = new byte[Lenght + 6];
Step = 1;
}
else if(Step == 1)
{
for (int packetCounter = 0; packetCounter < Lenght + 6; packetCounter++)
{
packet[packetCounter] = buffer[i++];
}
allPacket.Add(packet);
Step = 0;
}
}
}
catch { }
}
虽然我同意内置LINQ不适合不规则分组,但如果您愿意在之后验证包,或者可能有较差的错误处理,则扩展方法可以使用简单的LINQ语句。
此扩展方法通过使用确定下一个"块"大小的方法对数据进行分组。的数据,基于数据。
public static class LINQExt {
// int ChunkSizeFn(T[] data, int start) - returns size of chunk at start
public static IEnumerable<T[]> GroupByFunc<T>(this T[] data, Func<T[], int, int> ChunkSizeFn) {
int offset = 0;
while (offset < data.Length) {
var currentChunkLen = ChunkSizeFn(data, offset);
yield return new ArraySegment<T>(data, offset, currentChunkLen).ToArray();
offset += currentChunkLen;
}
}
}
使用这个扩展方法,您可以取出块:
var allPackages = buffer.GroupByFunc((data,start) => (data[start+2] << 8) + data[start+3] + 6).ToList();
仅过滤具有有效头的包,添加Where
:
var allPackages = buffer
.GroupByFunc((data,start) => (data[start+2] << 8) + data[start+3] + 6)
.Where(p => p[0] == 'xAA' && p[1] == 'xFE')
.ToList();