Делает Java чтение чисел в прямом порядке байтов или обратный порядок байтов?


Я спрашиваю, потому что я посылаю поток байтов из процесса C в Java. На стороне C 32-разрядное целое число имеет LSB-это первый байт, а MSB-4-й байт.

Итак, мой вопрос: на стороне Java, когда мы читаем байт, как он был отправлен из процесса C, что такое прямой на стороне Java?

следующий вопрос: если endian на стороне Java не совпадает с отправленным, как я могу конвертировать между ними?

6 86

6 ответов:

использовать в сетевом порядке байтов (обратный порядок байтов), который является таким же, как Java так или иначе использует. Смотрите man htons для разных переводчиков в C.

я наткнулся здесь через Google и получил свой ответ, что Java-это big endian.

читая ответы, я хотел бы отметить, что байты действительно имеют порядок endian, хотя, к счастью, если вы имели дело только с "основными" микропроцессорами, вы вряд ли когда-либо сталкивались с этим, поскольку Intel, Motorola и Zilog все согласились с направлением сдвига своих чипов UART и что MSB байта будет 2* * 7, а LSB будет 2* * 0 в их процессорах (я использовал мощность FORTRAN обозначение, чтобы подчеркнуть, насколько стар этот материал:)).

Я столкнулся с этой проблемой с некоторыми данными последовательного нисходящего канала Space Shuttle 20+ лет назад, когда мы заменили аппаратное обеспечение интерфейса $10K на компьютер Mac. Есть технический отчет НАСА, опубликованный об этом давно. Я просто использовал таблицу поиска 256 элементов с обратными битами (таблица[0x01]=0x80 и т. д.) после того, как каждый байт был перемещен из битового потока.

в Java нет целых чисел без знака. Все целые числа подписаны и в большом конце.

на стороне C каждый байт имеет Tne LSB в начале слева и MSB в конце.

похоже, что вы используете LSB как наименее значимый бит, не так ли? LSB обычно означает наименее значимый байт. Endianness не на основе битов, а на основе байтов.

для преобразования из байта без знака в Java целое число:

int i = (int) b & 0xFF;

для преобразования из unsigned 32-bit little-endian в byte[] в Java long (с верхней части моей головы, не проверено):

long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;

это никак не может повлиять на что-либо в Java, так как нет (прямого не-API) способа отображения некоторых байтов непосредственно в int в Java.

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

Я бы читал байты один за другим, и объединить их в долго значение. Таким образом, вы контролируете endianness, и процесс общения прозрачен.

Если он соответствует используемому протоколу, рассмотрите возможность использования DataInputStream, где поведение очень хорошо определены.