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

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

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

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


person hhafez    schedule 12.12.2008    source источник
comment
Вот моя мнемоника, поэтому я не забуду: Java - это не аппаратное обеспечение, а виртуальный язык, это язык Интернета. сетевой порядок байтов - прямой порядок байтов. Следовательно, Java является прямым порядком байтов.   -  person eigenfield    schedule 21.06.2020


Ответы (8)


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

person Egil    schedule 12.12.2008
comment
Я сейчас не в своем Linux-боксе, но является ли htons одной из стандартных библиотек? - person hhafez; 12.12.2008
comment
Согласно h30097.www3.hp.com / docs // base_doc / DOCUMENTATION / V51_HTML / MAN / его часть стандартной библиотеки c, да - person Egil; 12.12.2008
comment
Я попробую в следующий понедельник, но это выглядит многообещающе - person hhafez; 12.12.2008
comment
htons доступен почти везде, но не в ISO C. - person MSalters; 12.12.2008
comment
Если вам нужно использовать что-то другое, кроме сетевого порядка байтов, то вы можете либо использовать собственные побитовые операторы, либо использовать различные версии java.nio.Buffer. - person Darron; 13.12.2008
comment
Согласно его справочной странице, он определен в POSIX.1, поэтому он должен быть доступен практически везде. И я, кажется, помню, как использовал его в Win32, так что он не только в системах POSIX. - person Joachim Sauer; 13.12.2008
comment
Тьфу, черт побери с прямым порядком байтов. Почему кто-то все еще использует это, когда все популярные архитектуры процессоров имеют прямой порядок байтов? /ворчать. - person Timmmm; 12.11.2015

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

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

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

person WB Greene    schedule 08.12.2011
comment
Отличное понимание! У меня есть этот вопрос и нет ответов в сети. - person Xolve; 28.08.2013
comment
Если какие-то из них будут общедоступными, не могли бы вы связать технический отчет НАСА (и, возможно, последовательные данные нисходящей линии связи космического челнока), о которых вы говорите? было бы интересно, я никогда не видел ничего подобного. - person n611x007; 08.11.2013
comment
Побитовый порядок байтов также играет важную роль в форматах сжатия, которые используют некоторую форму кодирования Хаффмана (то есть все они). Для дополнительного развлечения, JPEG имеет побитовый обратный порядок байтов (т.е. самый старший бит - это первый бит), а LZ - побитовый прямой порядок байтов. Однажды я работал над проприетарным форматом сжатия, который использовал оба формата под капотом. О, это было весело ... - person user435779; 05.08.2014
comment
Начав с битов, я долгое время думал, что ЭТО и есть порядок байтов. - person Roy Falk; 30.03.2016

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

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

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

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

int i = (int) b & 0xFF;

Чтобы преобразовать из беззнакового 32-битного 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;
person Jonas Elfström    schedule 12.12.2008
comment
просто понял, что: $ Итак, как я должен отправить этот неподписанный маленький порядок байтов в мой Java-процесс, чтобы прочитать его правильно? - person hhafez; 12.12.2008
comment
Что я имею в виду под началом, это то, что lsb находится в начале 4 байтов (это 32-битное int без знака), поэтому я имел в виду наименее значимый байт - person hhafez; 12.12.2008
comment
Также конвертирую с C - ›Java не с Java -› C :) - person hhafez; 12.12.2008
comment
Ваш код работает нормально, если вы удалите точку с запятой после 0xFF в последних трех строках. Я бы отредактировал это сам, но это изменение менее чем на 6 символов. - person Moose Morals; 04.03.2016
comment
Прошло почти 8 лет, но наконец кто-то заметил синтаксическую ошибку. Спасибо @MooseMorals :) - person Jonas Elfström; 04.03.2016

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

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

person Joachim Sauer    schedule 12.12.2008
comment
Конечно, есть. Двоичная математика (&, |, ‹< и т. Д.) Отлично работает с байтами и целыми числами. Достаточно легко взять произвольные байты и вставить их в целое число. - person Herms; 13.12.2008
comment
Но если вы это сделаете, вы все равно не сможете определить, какой порядок байтов использует ваша JVM для внутренних целей. - person Darron; 13.12.2008
comment
Да, но даже там вы напрямую не сопоставляете. Вы используете арифметику, которая делает именно то, что вы ей говорите, нет двусмысленности. В C вы всегда можете преобразовать байт * в long * и отменить ссылку на него. Тогда вам придется позаботиться о порядке байтов. В Java нет прямого двусмысленного способа сделать это. - person Joachim Sauer; 13.12.2008
comment
Ах я вижу. Вы говорили о актерском составе, а не о двоичной математике. Да, в таком случае ты прав. - person Herms; 15.12.2008
comment
+1 для поиска документации, но ПРИМЕЧАНИЕ: 1-е предложение больше неверно, поскольку в настоящее время пакет NIO предлагает ByteBuffer, который может отображать байты в примитивы, и где вы можете изменить порядок байтов. См. ByteBuffer и ByteOrder - person user85421; 12.04.2011

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

person Wouter Lievens    schedule 12.12.2008
comment
Не хотите прокомментировать, почему вы голосуете за меня? - person Wouter Lievens; 12.12.2008
comment
потому что даже если я буду читать каждый байт по отдельности, порядок байта, который отправляется, будет неправильным, поэтому мне нужно будет его преобразовать - person hhafez; 13.12.2008
comment
Порядок байтов? Что это за фигня? Слова чувствительны к порядку байтов, отдельные байты - нет. - person Wouter Lievens; 19.02.2009
comment
@hhafez Это неправда, байты не имеют порядка байтов, насколько нам нужно беспокоиться, если вы читаете побайтно, вы, программист, несете ответственность за назначение байтов в нужное место. Это именно то, что делает DataInputStream, он просто собирает байты вместе с прямым порядком байтов под капотами. - person nos; 20.08.2010
comment
@WouterLievens: я столкнулся с некоторыми устройствами ввода-вывода (например, микросхемой часов реального времени), которые по какой-либо причине отправляют данные в формате с обратным битом; после получения от них данных необходимо поменять местами биты в каждом байте. Я согласен с вами, однако, что порядок байтов в байтах не является в целом проблемой, если только не приходится иметь дело с конкретными аппаратными средствами странной конструкции. - person supercat; 17.12.2013
comment
Думаю, это может быть что-то вроде FIFO / LIFO. Интересный анекдот :) - person Wouter Lievens; 18.12.2013
comment
@WouterLievens Извините, не могли бы вы помочь мне понять, что вы имеете в виду: слова "имеют" чувствительны к порядку байтов, а отдельные байты - нет. Я запуталась со словами у сомнительных ... ??? - person Koray Tugay; 20.01.2016
comment
Это грамматическая ошибка. Я хотел сказать там (семь лет назад ?!), что слова имеют порядок байтов, а байты, как правило, нет, потому что порядок байтов (неформально) заключается в том, как арифметически объединить байты в слово. - person Wouter Lievens; 20.01.2016
comment
@WouterLievens Меня смущает одна вещь. Мы говорим о порядке байтов в регистре ЦП, порядке байтов в памяти, порядке байтов на диске или обо всем этом? - person Koray Tugay; 20.01.2016
comment
Я думаю, все они - person Wouter Lievens; 20.01.2016
comment
@WouterLievens Джим здесь stackoverflow.com/questions/4504775/ говорит иначе, поэтому я запутался .. - person Koray Tugay; 21.01.2016

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

person Ilja Preuß    schedule 12.12.2008
comment
Он может сделать это только в том случае, если в его протоколе используется такой же порядок байтов. - person Wouter Lievens; 12.12.2008
comment
Я исправил ссылку и изменил ее на Java 9, текущую версию. Однако рассматриваемый API был представлен в Java 1.0. - person Jens Bannmann; 15.11.2017

Как отмечалось выше, Java имеет "обратный порядок байтов". Это означает, что MSB int находится слева, если вы исследуете память (по крайней мере, на процессоре Intel). Знаковый бит также находится в MSB для всех целочисленных типов Java.
Чтение 4-байтового целого числа без знака из двоичного файла, хранящегося в системе с прямым порядком байтов, требует некоторой адаптации в 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;        
 }
person Donald W. Smith    schedule 18.02.2019
comment
К чему относится упомянутое выше? Порядок отображения ответов SO может варьироваться. - person LarsH; 11.05.2020

java force действительно big endian: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11

person user12482548    schedule 04.12.2019
comment
Это касается порядка байтов инструкций байт-кода, а не порядка байтов данных во время выполнения. - person kaya3; 05.12.2019
comment
Я голосую. Этот фрагмент byte[] bbb = ByteBuffer.allocate(4).putFloat(0.42f).array(); создал массив byte, противоположный тому, что было создано моим C/C++. Следовательно, обратный порядок байтов в Java действует даже в данных во время выполнения. - person eigenfield; 21.06.2020