Java преобразует 4 байта в int
мне было интересно, если решение этого документально здесь все еще решение или есть какой-либо другой способ получить int из 4 байтов?
спасибо.
EDIT: im получает байт[] из сокетов .читать
изменить: int recvMsgSize = in.read(Data, 0, BufferSize);
Если recvMsgSize равно -1, Я знаю, что соединение было удалено.
как это обнаружить, когда im использует DataInputStream вместо InputStream?
спасибо.
изменить: извиняюсь за то, что я yoyo относительно принятия правильного ответа. но после обновленного окончательного ответа mihi, похоже, что метод является твердым и сокращает расширенное кодирование и, на мой взгляд, лучшую практику.
5 ответов
в зависимости от того, где вы получаете эти 4 байта от:
http://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readInt()
http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#getInt(int)
вы, конечно, можете сделать это вручную, но в большинстве случаев с помощью одного из них (если вам нужно преобразовать массив байтов с большим количеством байтов, вы можете использовать DataInputStream
вокруг ByteArrayInputStream
например) облегчающий.
редактировать: Если вам нужно изменить endianness, вам придется использовать ByteBuffer, или отменить байты самостоятельно, или сделать преобразование самостоятельно, так как DataInput не поддерживает изменение endianness.
Edit2: когда вы получаете их из входного потока сокета, я бы обернул это в DataInputStream
и использовать его для чтения всех видов данных. Тем более, что InputStream.read (byte[]) не гарантирует заполнения всего массива байтов... DataInputStream.readFully делает.
DataInputStream in = new DataInputStream(socket.getInputStream());
byte aByte = in.readByte();
int anInt = in.readInt();
int anotherInt = in.readInt();
short andAShort = in.readShort(); // 11 bytes read :-)
byte[] lotOfBytes = new byte[anInt];
in.readFully(lotOfBytes);
Edit3: при чтении несколько раз из потока, они будут продолжать читать там, где вы остановились, я. e. aByte будет байтом 0, anInt будет байтами от 1 до 4, anotherInt будет байтами от 5 до 8 и т. д. readFully будет читать дальше после всего этого и будет блокировать, пока он не прочитал lotOfbytes
.
когда поток останавливается (соединение падает), вы получите EOFException
вместо -1, поэтому, если вы получите -1, int действительно был -1.
если вы не хотите разбирать байты вообще, вы можете пропустить() их. Разбор одного байта двумя разными способами невозможен с помощью DataInputStream (i. e. прочитайте сначала int от байта 0 до 3, затем один от байта 2 до 5), но обычно не требуется.
пример:
// read messages (length + data) until the stream ends:
while (true) {
int messageLength;
try {
messageLength = in.readInt(); // bytes 0 to 3
} catch (EOFException ex) {
// connection dropped, so handle it, for example
return;
}
byte[] message = new byte[messageLength];
in.readFully(message);
// do something with the message.
}
// all messages handled.
надеюсь, что это ответы на ваши дополнительные вопросы.
вы должны быть очень осторожны с любым расширением преобразования и числового продвижения, но код ниже преобразует 4 byte
на int
:
byte b1 = -1;
byte b2 = -2;
byte b3 = -3;
byte b4 = -4;
int i = ((0xFF & b1) << 24) | ((0xFF & b2) << 16) |
((0xFF & b3) << 8) | (0xFF & b4);
System.out.println(Integer.toHexString(i)); // prints "fffefdfc"
см. также
-
код Java для преобразования байта в шестнадцатеричный
- обратите внимание на необходимость маски с
& 0xFF
-- вы, вероятно, в конечном итоге сделать много этого, если вы работаете сbyte
так как все арифметические операции способствуютint
(илиlong
)
- обратите внимание на необходимость маски с
если у вас их уже есть в byte[]
массив, вы можете использовать:
int result = ByteBuffer.wrap(bytes).getInt();
или, если у вас есть Google гуава-библиотеки на вашем пути к классам у вас есть ярлык:
int result = Ints.fromByteArray(array);
который имеет то преимущество, что у вас есть аналогично хорошие API для других типов (Longs.fromByteArray
, Shorts.fromByteArray
и т. д.).
решение в функциональном стиле (только для разнообразия, имхо не очень удобно в использовании):
private int addByte (int base, byte appendix) {
return (base << 4) + appendix;
}
public void test() {
byte b1 = 5, b2 = 5, byte b3 = 0, b4 = 1;
int result = addByte (addByte (addByte (addByte (0, b1), b2), b3), b4);
}
Как сказал Михи, это зависит от того, откуда вы получаете эти байты, но этот код может быть полезен:
int myNumber = (((int)byteOne) << 0) |
(((int)byteTwo) << 8) |
(((int)byteThree) << 16) |
(((int)byteFour) << 24);