Типы данных Java в байтовом массиве - PullRequest
3 голосов
/ 28 сентября 2011

У меня есть класс Java

public class MsgLayout{
int field1;
String field2;
long field3;
}

Я должен записать этот объект в виде байтового массива в выходной поток Socket.Три поля (переменные экземпляра) имеют макет.то есть field1 должен занимать 1 байт, field2 должен занимать 4 байта и field3 должен занимать 8 байтов.

ByteBuffer bbf = ByteBuffer.allocate(TOTAL_SIZE);
bbf.put(Integer.toString(this.getField1()).getBytes(), 0, FIELD1_SIZE);
bbf.position(FIELD2_OFFSET);
bbf.put(Long.toString(this.getField2()).getBytes(), 0, FIELD2_SIZE);
bbf.position(FIELD3_OFFSET);
bbf.put(Long.toString(this.getField3()).getBytes(), 0, FIELD3_SIZE);
byte[] msg = bbf.array();

Используя приведенный выше код, я пытаюсь вписать каждое поле в байтовый массивв соответствии с желаемым размером.Но я получаю IndexOutOfBoundException Короче говоря, проблема заключается в том, как подогнать поля под размер, определенный макетом.Например, FIELD1_OFFSET = 0, FIELD1_SIZE=1, FIELD2_OFFSET=1, FIELD2_SIZE=4, FIELD3_OFFSET=5, FIELD3_SIZE=8. Теперь, когда я конвертирую field1 в строку, он не помещается в 1 байт при преобразовании в байт [].Если я не конвертирую в String и не использую putInt (int), он записывает 4 байта в результирующий байтовый массив.

Ответы [ 2 ]

2 голосов
/ 28 сентября 2011

В настоящее время ваш код выполняет кодирование ваших числовых полей в виде строк с последующим выводом байтов этих символов.

Я бы предложил использовать класс DataOutputStream, чтобы обернуть ваш поток SocketOutput и записать ваши двоичные данные следующим образом:

DataOutput output = new DataOutputStream(socketOutputStream);

int field1 = 1;
String field2 = "Hello";
long field3 = 5000000000L;

output.writeByte(field1);
output.writeBytes(field2.substring(0, 3));
output.writeLong(field3);

В этом коде есть пара предположений. Сначала я предполагаю, что для поля 2 вы хотите, чтобы 4 символа сериализовались как один байт каждый. Если вы хотите выполнить любое многобайтовое кодирование с использованием чего-то вроде UTF-8, то вам нужно сделать что-то немного по-другому. Во-вторых, я предполагаю, что поле 2 всегда будет содержать не менее 4 символов.

0 голосов
/ 28 сентября 2011

field1 может иметь только один байт данных, но его строковое представление будет одним или несколькими символами (например, "0", "63", "127").Каждый символ в строке на самом деле является char (двухбайтовое значение).Таким образом, я ожидаю, что один байт данных будет раздуваться до двух-шести байтов данных, когда он проходит преобразование byte-> String-> byte [].

...