Разбор двоичных данных

У меня есть приложение, которое получает данные в двоичном виде через Bluetooth. Я читаю данные, используя inputtream из bluetoothsocket в байт []. Но я должен проанализировать все сообщения, потому что они должны иметь заданный формат, чтобы быть действительными. Все сообщения в двоичном виде.

Моим решением было преобразовать byte[] в строку, а затем разбить строку и проанализировать все полученные сообщения.

Пример разбора данных: 0000000010000001

я должен знать, что первые 8 нулей - это заголовок, а 10000001 - реальные данные.

Моя идея состояла в том, чтобы создать строку (из байта []), которая представляет -> 0000000010000001, используя новую строку (byte[]), а затем разделить всю строку в один байт и проверить значение, например:

строка1 имела 00000000 строка2 имела 10000001

я знаю, что 8 нулей являются заголовком, поэтому string2 имеет представление данных.

Мой вопрос об эффективности этого метода. Это лучший способ сделать это в мобильной среде?

4 ответа

Решение

Манипулирование строками для анализа двоичных данных довольно неэффективно с точки зрения скорости, потребления памяти, а также накладывает определенную нагрузку на сборщик мусора - потому что вы всегда генерируете новые строковые объекты и сразу же забываете их.

В Java у вас есть несколько вариантов сделать это лучше:

  • DataInputStream: это обертка для InputStream где вы читаете байты, шорты, длинные, двойные и т. д. прямо из потока.
  • Используя NIO ByteBuffers и "производные" типы, такие как ShortBuffer... они хороши для передачи больших объемов данных, а также для двоичного анализа.

Пока ваши данные выровнены по байтам, это простые способы. Если это не так - тогда лучше узнать, как выполнять битовые манипуляции с помощью таких операторов, как &, |, ~, <<, >>,

Я предлагаю вам придерживаться DataInputStream как можно дольше.

Только для справки, есть бесплатная библиотека OSS, называемая Java Binary Block Parser (JBBP), она совместима с Android (2.1+) и позволяет просто описывать структуру данных в текстовом формате и автоматически анализировать поток данных (или массив), если вы хотите для разбора всего потока на биты он может быть выполнен в одной строке

byte [] parsedBits = JBBPParser.prepare("bit:1 [_];").parse(new byte[]{1,2,3,4,5}).findFieldForType(JBBPFieldArrayBit.class).getArray();

Строки - наименее эффективный способ сделать это действительно.

Если ваш бинарный 0000000010000001 на самом деле byte[] {0, 0, 0, 0, 2, 0, 0, 1} в десятичном, затем просто проверьте, если b[0] == b[1] == b[3] == b[4] == 0,

Редактировать: игнорировать "в десятичной" части, это не имеет значения, если вы хотите только проверить, если ваш массив начинается с 00000000 (т.е. 4 нулевых байта)

Это очень низкоэффективный способ, и не рекомендуется. Чтобы анализировать двоичные данные, у нас должен быть протокол и всегда использовать битовую операцию. Если вы не знакомы с этим,

FastProto - лучший выбор, вам нужно аннотировать поля объекта данных, FastProto поможет вам завершить все.

Представьте, что двоичные данные имеют фиксированную длину 20 байт:

65 00 7F 69 3D 84 7A 01 00 00 55 00 F1 FF 0D 00 00 00 07 00

Двоичные данные содержат 3 различных типа сигналов, конкретный протокол выглядит следующим образом:

      import org.indunet.fastproto.annotation.*;

public class Weather {
    @UInt8Type(offset = 0)
    int id;

    @TimeType(offset = 2)
    Timestamp time;

    @Int16Type(offset = 12)
    int temperature;
}

byte[] bytes= ...   // binary need parsing

Weather weather = FastProto.parse(datagram, Weather.class);

Возможно, вы заметили, что FastProto описывает информацию о полях в двоичных данных с помощью аннотаций, что очень просто и эффективно.

Другие вопросы по тегам