Как правильно преобразовать поток данных?

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Закрыто
heartbeatMe
Сообщения: 6
Зарегистрирован: 11 дек 2013, 17:41

Как правильно преобразовать поток данных?

Сообщение heartbeatMe » 11 дек 2013, 18:00

На смартфон поступает поток данных с внешнего устройства через bluetooth модуль в следующем виде:
| мл.байт | ст.байт | '\r' | '\n' |
Необходимо преобразовывать полученные байты в short и отсеивать (либо использовать по назначению - синхронизация) символы \r\n.
Что я делаю сейчас:

Код: Выделить всё

byte[] readBuf = (byte[]) msg.obj;
data_length = msg.arg1;
String readString = new String(readBuf, 0, msg.arg1);
readString = readString.replaceAll("\r\n", "");
byte[] byteToShort = readString.getBytes();
short[] shorts = new short[byteToShort.length/2];    
ByteBuffer.wrap(byteToShort).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
На сколько верен такой подход к решению задачи?

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Как правильно преобразовать поток данных?

Сообщение altwin » 11 дек 2013, 19:50

если я правильно понял вопрос... читая данные в буфер вы никогда не можете предсказать объем следующего пакета, потому читать нужно по байтам. да и смысла замены последовательности символов "\r\n" пустой строкой не совсем понятна.
Трудно что -то говорить не понимая, что происходит, но по сути обычно вы читаете простым read() входящий поток по байтам и помещаете в стек, далее делаете, с ними что хотите. Т.е. к примеру если хотите что -то отсеять, то дальше просто проходите циклом и по условию делаете, что хотите... Зачем вы пытаетесь сделать строку из байт не ясно, может проблема в том, что из куска кода трудно что -то понять и делать хоть какие-то не глупые выводы...
Если же нужно просто преобразовать byte в short, очевидными путями богат google, к примеру:

Код: Выделить всё

int size = byteArray.length;
short[] shortArray = new short[size];

for (int index = 0; index < size; index++)
    shortArray[index] = (short) byteArray[index];
Изображение

heartbeatMe
Сообщения: 6
Зарегистрирован: 11 дек 2013, 17:41

Re: Как правильно преобразовать поток данных?

Сообщение heartbeatMe » 12 дек 2013, 12:05

Спасибо за ответ. Сейчас данные передаются непрерывным потоком в режиме онлайн. Пакетом можно назвать последовательность байтов | мл.байт | ст.байт | '\r' | '\n' |
Со чтением потока проблем нет, вопрос как раз относится к части "делаем далее с ним что хотим" :) Преобразовывая массив байтов в строку и заменяя пустой строкой символы, пытаюсь получить "чистый" массив из мл. и ст. байтов. Потому что каждый из символов \r и \n также занимают по байту. Эта часть кода как раз и вызывает сомнения, подобные Вашим. Если это не правильно, то как убрать из массива байтов "\r\n", либо еще лучше грамотно использовать их для синхронизации.
Предложенный Вами вариант преобразования не подходит хотя бы потому, что short состоит из 2 байтов

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Как правильно преобразовать поток данных?

Сообщение altwin » 12 дек 2013, 12:34

Ну то, что short состоит из 2-х байт говорит только о том, что преобразовать можно без потери точности. есть еще такая штука, как ByteBuffer:

Код: Выделить всё

ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(firstByte);
bb.put(secondByte);
short shortVal = bb.getShort(0);
а по поводу \r\n, нужно исходить из того, как вы работаете вариантов куча, к примеру если вы все равно пытались преобразовать поток в строку - можно поместить данные в файл и читать построчно, тогда \r\n будут игнорироваться и лишь сообщать читающему методу о начале следующей строки. Да и просто в цикле можно сделать банальное:

Код: Выделить всё

for(;;) (b == "\r" || b == "\n") ? continue : ... ;
но вообще мне не понятно, почему вы преобразуете в short, а не к примеру в int -ы по разделителю(которым может быть \r\n).
Изображение

heartbeatMe
Сообщения: 6
Зарегистрирован: 11 дек 2013, 17:41

Re: Как правильно преобразовать поток данных?

Сообщение heartbeatMe » 12 дек 2013, 14:55

altwin писал(а):но вообще мне не понятно, почему вы преобразуете в short, а не к примеру в int -ы по разделителю(которым может быть \r\n).
Буду очень благодарен, если Вы подробней расскажите, как это сделать. Просто полученное целое число должно быть в диапазоне от минус 32768 до плюс 32767

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Как правильно преобразовать поток данных?

Сообщение altwin » 12 дек 2013, 16:02

Код: Выделить всё

short high=(-48 & 0x00ff);
short low=80;

int c= ((high & 0xFF) << 8) | (low & 0xFF);
возможно этот ответ поможет http://stackoverflow.com/a/12288979/2611075

P.S. конечно если важен диапазон значений, то врятли это все поможет. Возможно проще будет поискать какую -то высокоуровневую библиотеку способную делать то, что вы хотите. Или же просто использовать что -то вроде http://developer.android.com/reference/ ... apter.html. Трудно думать, мне не совсем понятна потребность обрабатывать поток byte, неизвестных слишком много.
Изображение

Mykola
Сообщения: 132
Зарегистрирован: 26 июл 2013, 12:06

Re: Как правильно преобразовать поток данных?

Сообщение Mykola » 12 дек 2013, 17:47

http://commons.apache.org/proper/common ... mmary.html не?

ПС: У меня дежавю.

Закрыто