简体   繁体   English

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

[英]Splitting a streaming hexadecimal string into smaller chunks

I have a stream of hex data coming from a serial device, in this format: 我有一个来自串行设备的十六进制数据流,格式为:

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

What I need to do (in C#) is read the incoming string, and split it into chunks at 'F4', for processing. 我需要做的(在C#中)是读取传入的字符串,并将其拆分为“ F4”的块,以进行处理。 So that I get: 这样我得到:

string DataToProcess = "F4 01 09 05 05";

that updates as every section comes in. 随着每个部分的到来而更新。

I am a bit stuck as to the best way to approach this. 我对解决此问题的最佳方法有些困惑。

I have: 我有:

byte[] data = new byte[count];
 _serialPort.Read(data, 0, data.Length);

string rawString = BitConverter.ToString(data, 0);

if (rawString.Contains("F4"))
{
     //split here?                    
}

As it is a live stream, the count variable is always changing. 由于它是实时流,因此count变量总是在变化。 How can I 'wait' for an F4 , and create a substring from a section? 如何“等待” F4并从部分创建子字符串?

Thank you. 谢谢。

I suggest grouping data , without converting the array into string 我建议对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

Test 测试

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

Console.Write(report);

Outcome 结果

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

You can use string.Split(string[], StringSplitOptions) mixed with LINQ to split by each F4 : 您可以使用与LINQ混合使用的string.Split(string[], StringSplitOptions)来按每个F4进行分割:

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

Use a fixed-size buffer and parse data as it comes in. Something like: 使用固定大小的缓冲区并解析传入的数据。类似:

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
}

Notice that example above uses ASCII decoding instead of BitConverter.ToString . 请注意,上面的示例使用ASCII解码而不是BitConverter.ToString If you need to work with bytes instead, why convert it to a String in the first place? 如果您需要使用字节代替,为什么要首先将其转换为String You can work with bytes as well, C# supports a syntax like 0xF4 , that would represent a number in hex format. 您也可以使用字节,C#支持类似于0xF4的语法,该语法表示十六进制格式的数字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM