Не удается прочитать данные Java, сериализованные в С++

У меня есть клиент Java, подключенный через сокет к серверу С++.

Сервер С++ отправляет обратно в сериализованные объекты клиента.

Однако сериализация работает по-разному для Java и С++, поэтому я не могу читать объекты таким образом:

objectInputStream.readObject();

Это заставляет меня читать каждое отдельное значение объекта вручную:

byte[] buffer = read(FOUR_BYTES);
int flag = convertBufferToInt(buffer);
byte[] buffer = read(FOUR_BYTES);
float price = convertBufferToFloat(buffer);
// More stuff
myObject.setFlag(flag);
myObject.setPrice(price);
// More stuff

Это очень сложно поддерживать. Нет ли более простого способа заполнить мой объект данными?

2 ответа

Да есть (есть). У вас есть 2 варианта, используя только стандартную библиотеку:

Используя DataInputStream класс

Ознакомьтесь с классом DataInputStream. Он имеет методы для чтения значений примитивных типов, таких как readByte(), readInt(), readLong(), readFloat(), readChar(), readUTF() (для чтения UTF-8, закодированный String) и т.д.

Итак, ваш код становится таким же простым, как:

// Obtain InputStream from Socket:
InputStream is = ...;
// Create DataInputStream:
DataInputStream dis = new DataInputStream(is);
myObject.setFlag(dis.readInt());
myObject.setPrice(dis.readFloat());

Используя ByteBuffer класс

Для этого вы должны сначала прочитать все данные в массив байтов. Как только вы это сделаете, вы можете создать ByteBuffer с помощью метода ByteBuffer.wrap(byte[] array). Класс ByteBuffer также поддерживает чтение примитивных типов, как класс DataInputStream.

Хорошая вещь о ByteBuffer заключается в том, что она поддерживает изменение порядка байтов (порядок чтения и записи младших и высоких байтов многобайтового значения, например int): ByteBuffer.order(ByteOrder bo). Это очень полезно, если вы общаетесь с системами, использующими порядок байтов differnet (который может применяться в вашем случае).

Пример использования ByteBuffer:

// Read all your input data:
byte[] data = ...;
// Create ByteBuffer:
ByteBuffer bb = ByteBuffer.wrap(data);
myObject.setFlag(bb.getInt());
myObject.setPrice(bb.getFloat());


Чтобы решить эту проблему, вам нужно будет написать парсер С++ для объектов, сериализованных в Java. Это немалая задача.

Скорее, я бы рекомендовал вам найти формат сериализации, который легко разобрать и разделить между вашими Java и С++-программами. Предпочтительно формат, в котором существуют Java, а также библиотеки С++ для сериализации/десериализации. JSON или Буферы протокола Google являются очевидными кандидатами.

licensed under cc by-sa 3.0 with attribution.