разные результаты при преобразовании int в массив байт — .NET vs Java

#c# #java

#c# #java

Вопрос:

Я пытаюсь отправить данные с Java-клиента на сервер c # и у меня возникают проблемы с преобразованием int в массив байт.

когда я конвертирую число 8342 с помощью c #, используя этот код:

 BitConverter.GetBytes(8342)
  

результат таков: x[4] = { 150, 32, 0, 0 }

с Java я использую:

 ByteBuffer bb = ByteBuffer.allocate(4); 
bb.putInt(8342); 
return bb.array();
  

и вот результат: x[4] = { 0, 0, 32, -106 }

Кто-нибудь может объяснить? Я новичок в Java, и это первый раз, когда я вижу отрицательные числа в массивах байтов.

Ответ №1:

Вы должны изменить порядковый номер:

  bb.order(ByteOrder.LITTLE_ENDIAN)
  

Java хранит данные внутри как большой порядковый номер, в то время как .NET по умолчанию имеет начальный порядковый номер.

Также существует разница в подписанном и неподписанном между Java и .NET. Java использует байты со знаком, C # — без знака. Это тоже придется изменить.

В принципе, именно поэтому вы видите -106 (150-256)

Вам нужно будет сделать что-то вроде приведенного ниже служебного метода:

 public static void putUnsignedInt (ByteBuffer bb, long value)
    {
       bb.putInt ((int)(value amp; 0xffffffffL));
    }
  

Обратите внимание, что значение long.

Комментарии:

1. Что ж, ByteBuffer документирован (так что чтение jdoc помогло бы) для использования BigEndian по умолчанию, но на самом деле это интересный вопрос, определяет ли Java используемый порядок байтов? Я сомневаюсь в этом — это было бы намного более высокой производительностью и в любом случае не было бы заметно (за исключением случаев записи выходных данных, и мы можем легко преобразовать их туда в соответствии с документацией)

2. Я думаю, что теперь результат будет -106, 32, 0, 0

3. После добавленной строки: ByteOrder. LITTLE_ENDIAN массив действительно изменил свои порядки. Чтобы сервер c # понял это, мне нужно изменить массив байтов на неподписанный. Есть ли способ указать ByteBuffer сделать это, или мне нужно изменить каждый байт?

4. @idan: -106 и 150 — это один и тот же байт; они просто по-разному преобразуются в строки или большие целые числа. Поскольку в Java нет способа представления байтов без знака, в Java невозможно представить 150 в виде байта.