2016-08-01 3 views
0

У меня есть поток шестнадцатеричных данных, поступающих из последовательного устройства, в следующем формате:Расщепление потоковый шестнадцатеричная строка на более мелкие куски

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

Является ли "F4" подстрока всегда такой же длины или число байтов от одного F4 до другого va ry также? –

+0

Такая же длина. Но поток не может начинаться с F4. – anti

+0

Я буду считать, что данные считываются в цикле. И следующая итерация начинается там, где заканчивается предыдущая. Таким образом, функция Read возвращает число ob байтов, которое может рассказать вам, сколько подстрок есть, остальные байты (которые меньше длины подстроки F4) должны быть сохранены и добавлены в начало массива данных в следующая итерация. –

ответ

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(); 
} 
+0

Привет, спасибо! Это дает мне ошибку: 'Ошибка \t CS0266 \t Невозможно неявно преобразовать тип System.Collections.Generic.IEnumerable в строку []. Явное преобразование существует (вы пропускаете листинг?) ' – anti

+1

Извините, я забыл добавить' .ToArray() ', исправленную проблему. –

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, который будет представлять число в шестнадцатеричном формате.

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 
+0

Спасибо! Это, похоже, дает мне разные результаты. Иногда только половина строки, а иногда и больше ... 'report =" 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, 15, 08, 13, 00, 00, 18, F0, 0C, 00, 00, 00, 00, 03, 00, 00, A3, 80, 04, 00, 00, 5C, 7F, 00 \ r \ nF4, 01, 09, 02, 05, 00, 02, 1D, 04, 06, 00, 03, A3, A3' – anti

+0

@anti: если у вас есть неправильный/неожиданный результат, укажите * встречный пример *, то есть 'data = new byte [] {....};' –

+0

Извините! См. ниже: значение 'count' изменяется при чтении данных, должен ли я ждать номер сертификата из байтов? (поток является живым при подключении i, поэтому может не начинаться с 'F4'. – anti

Смежные вопросы