Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将流式十六进制字符串拆分为更小的块_C#_String_Split_Serial Port - Fatal编程技术网

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

C# 将流式十六进制字符串拆分为更小的块,c#,string,split,serial-port,C#,String,Split,Serial Port,我有一个来自串行设备的十六进制数据流,格式如下: 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]; _serialPo

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

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
,并从节中创建一个子字符串


谢谢。

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

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

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

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

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

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解码而不是
位转换器.ToString
。如果您需要使用字节,为什么首先要将其转换为
字符串
?您也可以使用字节,C#支持类似于
0xF4
的语法,该语法表示十六进制格式的数字。

使用固定大小的缓冲区,并在数据进入时解析数据。比如:

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解码而不是
位转换器.ToString
。如果您需要使用字节,为什么首先要将其转换为
字符串
?您也可以使用字节,C#支持类似于
0xF4
的语法,该语法表示十六进制格式的数字。

我建议对
数据进行分组,而不将数组转换为字符串

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
结果

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

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

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
结果

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

“F4”子字符串是否总是相同的长度,或者从一个F4到另一个F4的字节数是否也不同?它是相同的长度。但是流可能不会从F4开始。我假设数据是在循环中读取的。下一次迭代从上一次迭代结束的地方开始。因此,Read函数返回读取的ob bytes数,它可以告诉您有多少子字符串,其余的字节(小于F4子字符串的长度)应该保存并在下一次迭代中添加到数据数组的开头。是“F4”子字符串总是相同的长度,或者从一个F4到另一个F4的字节数也不同?它是相同的长度。但是流可能不会从F4开始。我假设数据是在循环中读取的。下一次迭代从上一次迭代结束的地方开始。因此,Read函数返回读取的ob bytes数,它可以告诉您有多少子字符串,其余的字节(小于F4子字符串的长度)应该保存并在下一次迭代中添加到数据数组的开头。您好,谢谢!这给了我一个错误:
错误CS0266无法隐式转换类型System.Collections.Generic.IEnumerableto string[]。存在显式转换(是否缺少转换?
很抱歉,我忘记添加
.ToArray()
,问题已解决。您好,谢谢!这给了我一个错误:
错误CS0266无法隐式转换类型System.Collections.Generic.IEnumerableto string[]。存在显式转换(是否缺少转换?
很抱歉,我忘记添加
.ToArray()
,问题已解决。谢谢!这似乎给了我不同的结果。有时只有半行,有时更多<代码>报告=“F4,01,09,01,05,00,02,1C,A0,06,00,03,A3,40,07,00,05,29,E0,01,00,00,00,11,20,02,00,00,00,15,08,13,00,00,00,18,F0,0C,00,00,00,00,03,00,00,00,A3,80,04,00,00,00,5C,7F,00\r\r\nF4,01,09,02,02,05,00,02,02,02,1D,04,06,06,00,03,A3
:如果您有错误的结果,请提供一个反例,即,
data=newbyte[]{….}对不起!请参见以下内容:
count
的值随着数据的读取而变化,我是否应该等待一定数量的字节?(流在我连接时处于活动状态,因此可能不会从
F4
开始
int count=\u serialPort.BytesToRead;if(count>10){byte[]data=new byte[count];\u serialPort.Read(data,0,data.Length);int group=0;var result=data.GroupBy(item=>item==0xF4?++group:group).选择(chunk=>chunk.ToArray());字符串报告=string.Join(Environment.NewLine,result.Select(array=>string.Join(,),array.Select(item=>item.ToString(“X2”;))
谢谢!这似乎给了我不同的结果。有时只有半行,有时更多…
报告="F4、01、09、01、05、00、02、1C、A0、06、00、03、A3、40、07、00、05、29、E0、01、00、00、11、20、02、00、00、00、15、08、13、00、00、00、18、F0、0C、00、00、00、00、00、00、00、00、A3、80、04、00、00、00、5C、7F、00\r\nF4、01、09、02、05、05、00、02、02、1D、04、06、06、00、00、00、03、03、A3
@anti:如果您有错误的结果,请提供一个计数器示例,例如:
data=new byte[]{..};
抱歉!请参见下面:读取数据时,
count
的值会发生变化,我是否应该等待一定数量的字节?(流在连接时处于活动状态,因此可能不会从
F4
开始
int count=\u serialPort.BytesToRead;if(count>10){byte[]data=new byte[count];_serialPort.Read(data,0,data.Length);int group=0;var result=data.GroupBy(item=>item==0xF4?++group:group)。选择(chunk=>chunk.ToArray());string report=string.Join(Environment.NewLine,result.Select(array=>string.Join(“,”,array