我有来自串行设备的十六进制数据流,格式如下:
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
,并从一个部分创建子字符串?
谢谢。
答案 0 :(得分:2)
我建议将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
答案 1 :(得分:1)
您可以使用string.Split(string[], StringSplitOptions)
与LINQ混合来按每个F4
进行拆分:
if (rawString.Contains("F4"))
{
string[] dataToProcess = rawString.Split(new string[] { "F4" }, StringSplitOptions.None).Select(l => "F4" + l).ToArray();
}
答案 2 :(得分:1)
使用固定大小的缓冲区并在数据进入时解析数据。例如:
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
之类的语法,它代表十六进制格式的数字。