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"

см. также


если у вас их уже есть в 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);