将流式十六进制字符串拆分为更小的块

本文关键字:拆分 十六进制 字符串 | 更新日期: 2023-09-27 17:59:41

我有一个来自串行设备的十六进制数据流,格式如下:

F4 01 09 05 05 F4 01 09 05 05 F4 F 01 09 05 05 F4 01 09 05 05 

我需要做的(在C#中)是读取传入的字符串,并在"F4"处将其分割成块进行处理。所以我得到:

string DataToProcess = "F4 01 09 05 05";

每个部分都会更新。

我有点纠结于如何最好地处理这个问题。

我有:

byte[] data = new byte[count];
 _serialPort.Read(data, 0, data.Length);
string rawString = BitConverter.ToString(data, 0);
if (rawString.Contains("F4"))
{
     //split here?                    
}

由于是实时流,count变量总是在变化。如何"等待"F4,并从节中创建子字符串?

谢谢。

将流式十六进制字符串拆分为更小的块

我建议分组data而不将数组转换为字符串

byte[] data = new byte[] {
    0xF4, 0x01, 0x09, 0x05, 0x05, ..., 0x09, 0x05, 0x05 };
// Using side effect in not the best practice, but helpful
int group = 0;
var result = data
  .GroupBy(item => item == 0xF4 ? ++group : group)
  .Select(chunk => chunk.ToArray());
//.ToArray(); // <- if you want to materialize

测试

string report = string.Join(Environment.NewLine, result
  .Select(array => string.Join(", ", array
     .Select(item => item.ToString("X2")))));
Console.Write(report);

结果

F4, 01, 09, 05, 05
F4, 01, 09, 05, 05
F4, 0F, 01, 09, 05, 05
F4, 01, 09, 05, 05

使用固定大小的缓冲区并在数据进入时解析数据

byte[] buffer = new byte[2048];
while (_serialPort.Read(data, 0, data.Length) > 0) {
    String rawString = Encoding.ASCII.GetString(buffer);
    String[] splitted = rawString.Split("'u00F4");
    // work with splitted
}

请注意,上面的示例使用ASCII解码而不是BitConverter.ToString。如果您需要使用字节,为什么首先要将其转换为String?您也可以使用字节,C#支持类似0xF4的语法,它将以十六进制格式表示数字。

您可以使用混合了LINQ的string.Split(string[], StringSplitOptions)来按每个F4:进行拆分

if (rawString.Contains("F4"))
{
    string[] dataToProcess = rawString.Split(new string[] { "F4" }, StringSplitOptions.None).Select(l => "F4" + l).ToArray();
}