Мне нужно закодировать Java-программу, которая будет получать сообщения из сети и отображать их содержимое для пользователя. Проблема в том, что сообщения, которые я получаю, представляют собой просто двоичные дампы структур C. Добавьте к этому, что некоторые из сообщений поступают из маленьких конечных машин, а некоторые из больших энтиантов, не преобразуя поля в порядок байтов сети. Один из способов - использовать JNI и преобразовать c structs в некоторую строку XML, а затем сериализовать эту XML-строку в Java-объект. Это трудоемкая работа, так как там около 122 различных структур, и каждая из них содержит более 20 полей. Интересно, есть ли библиотека/инструмент/методология, которая могла бы облегчить мою работу?
Использование C struct в Java
Ответ 1
Swig будет обрабатывать много утомительной повторяющейся работы для вас с точки зрения сопоставления структур C с объектами Java. Просмотрите руководство Swig/Java и запись на обертывания C структур.
Ответ 2
Существует библиотека под названием Preon, которая была разработана, чтобы помочь вам в этом типе задач: сайт Preon В основном, они пытаются сохранить все логика для чтения вашего pojo из двоичного потока в аннотации, привязанные к каждому полю вашего pojo.
Пример из своих документов, в которых вы контролируете размер int, который вы читаете:
class Rectangle
{
@BoundNumber(size="16") private int x1;
@BoundNumber(size="16") private int y1;
@BoundNumber(size="16") private int x2;
@BoundNumber(size="16") private int y2;
}
или для указания сущности:
class Rectangle
{
@BoundNumber(byteOrder=LittleEndian) private int x1;
@BoundNumber(byteOrder=LittleEndian) private int y1;
@BoundNumber(byteOrder=LittleEndian) private int x2;
@BoundNumber(byteOrder=LittleEndian) private int y2;
}
Вы можете даже использовать мини-уравнения со ссылками на значения в предыдущих полях, чтобы указать размер/длину и т.д.
@BoundList(size="width * height") byte[] pixels;
@BoundNumber(size="nrBits * 2") int value;
О, и они также предлагают условную логику, все в аннотациях.
Ответ 3
В этой области есть несколько библиотек. Один из самых простых в использовании (драйвер аннотации), безусловно, Preon
Ответ 4
Вы можете использовать DataInputStream
для загрузки данных из любого InputStream
. До тех пор, пока вы знаете точное расположение ваших структур, этого должно быть достаточно.
Ответ 5
java.nio имеет ByteBuffer, который поддерживает выборки байтов при чтении и записи, на лету, если это необходимо.