Java читает целые числа с прямым или прямым порядком байтов? - PullRequest
90 голосов
/ 12 декабря 2008

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

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

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

Ответы [ 7 ]

60 голосов
/ 12 декабря 2008

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

42 голосов
/ 08 декабря 2011

Я наткнулся здесь через Google и получил мой ответ, что Java имеет большой порядковый номер.

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

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

18 голосов
/ 12 декабря 2008

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

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

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

Чтобы преобразовать байт без знака в целое число Java:

int i = (int) b & 0xFF;

Для преобразования из беззнакового 32-разрядного байта с прямым порядком байтов [] в длинный Java (от макушки головы, не проверено):

long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;
11 голосов
/ 13 декабря 2008

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

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

3 голосов
/ 12 декабря 2008

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

3 голосов
/ 12 декабря 2008

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

0 голосов
/ 18 февраля 2019

Java - это Big-endian, как отмечено выше. Это означает, что MSB int находится слева, если вы исследуете память (по крайней мере, на процессоре Intel). Знаковый бит также находится в MSB для всех целочисленных типов Java.
Чтение 4-байтового целого числа без знака из двоичного файла, хранящегося в системе «Little-endian», требует некоторой адаптации в Java. Функция readInt () объекта DataInputStream ожидает формат с прямым порядком байтов.
Вот пример, который считывает четырехбайтовое значение без знака (как показано HexEdit как 01 00 00 00) в целое число со значением 1:

 // Declare an array of 4 shorts to hold the four unsigned bytes
 short[] tempShort = new short[4];
 for (int b = 0; b < 4; b++) {
    tempShort[b] = (short)dIStream.readUnsignedByte();           
 }
 int curVal = convToInt(tempShort);

 // Pass an array of four shorts which convert from LSB first 
 public int convToInt(short[] sb)
 {
   int answer = sb[0];
   answer += sb[1] << 8;
   answer += sb[2] << 16;
   answer += sb[3] << 24;
   return answer;        
 }
...