Java байтовые массивы и копирование в них целых - PullRequest
0 голосов
/ 27 декабря 2011

Какой лучший способ поместить int в определенную точку массива byte []?

Скажем, у вас есть байтовый массив:

byte[] bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int someInt = 12355; //0x43, 0x30

Как мне сделать bytes[4] = someInt;, чтобы байты [4] теперь равнялись 0x43, а байты [5] - 0x30?

Я привык просто использовать memcpy с C ++ и не знаю альтернатив в Java.

Спасибо

Ответы [ 5 ]

4 голосов
/ 27 декабря 2011

Если вы хотите, чтобы старшие 0 байтов int были помещены в byte[]:

void place(int num, byte[] store, int where){
    for(int i = 0; i < 4; ++i){
        store[where+i] = (byte)(num & 0xFF);
        num >>= 8;
    }
}

Если вы хотите, чтобы байты были только старшими ненулевыми байтами:

void place(int num, byte[] store, int where){
    while(num != 0){
        store[where++] = (byte)(num & 0xFF);
        num >>>= 8;
    }
}

Если вам нужен байты с прямым порядком байтов (старший байт с самым низким индексом), версия, в которой хранятся все четыре байта, очень проста, а другой немного сложнее:

void placeBigEndian(int num , byte[] store, int where){
    for(int i = 3; i >= 0; --i){
        store[where+i] = (byte)(num & 0xFF);
        num >>= 8;
    }
}

void placeBigEndian(int num, byte[] store, int where){
    in mask = 0xFF000000, shift = 24;
    while((mask & num) == 0){
        mask >>>= 8;
        shift -= 8;
    }
    while(shift > 0){
        store[where++] = (byte)((num & mask) >>> shift);
        mask >>>= 8;
        shift -= 8;
    }
}
2 голосов
/ 27 декабря 2011

Обратите внимание, вы предполагаете, что порядок байтов в порядке байтов! x86 имеет младший порядок байтов ... Более того, ваш int имеет длину 32 бита, следовательно 0x00004330 в старшем порядке

Если это то, что вам нужно, используйте ByteBuffer (по умолчанию используется порядок с прямым порядком байтов):

ByteBuffer buf = ByteBuffer.allocate(8);
// then use buf.putInt(yourint, index)
// buf.get(index) will read byte at index index, starting from 0
1 голос
/ 27 декабря 2011

Я не вижу проблемы, похоже, вы решили ее по-своему:

public static void putShort(bytes[] array, int position, short value)
{
    byte leftByte = (byte) (value >>> 8);
    byte rightByte = (byte) (value & 0xFF);

    array[position] = leftByte;
    array[position + 1] = rightByte;
}

Обратите внимание, что int равен 4 байта, а short - 2 байта.

0 голосов
/ 27 декабря 2011

Один из подходов заключается в использовании DataOutputStream и его метода writeInt (), обернутого вокруг ByteArrayOutputStream. например (без обработки ошибок)

public byte[] writeIntAtPositionX(int position, int iVal) throws IOException {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      DataOutputStream dos = new DataOutputStream(baos);

      // now, advancing to a specific spot is awkward.
      // presumably you are actually writing other stuff out before the integer
      // but if you really want to advance to a specific position

      for (int i = 0; i < position; i++)
         dos.writeByte(0);

      dos.writeInt(iVal);

      dos.flush();
      dos.close();
      return baos.toByteArray();  
   }

Большим преимуществом этого метода является то, что ребята, написавшие Java, выяснили порядок байтов и маскировку с помощью 0xFF и всего такого. Кроме того, если вы когда-нибудь планируете записывать в буфер значения типа double, shorts, longs или Strings и т. Д., Вам не нужно добавлять все эти методы, работа уже выполнена.

0 голосов
/ 27 декабря 2011

Прежде всего, в Java вам не нужно инициализировать байтовые массивы нулями. Все массивы инициализируются во время построения до 0 / false / null.

Во-вторых, int s - это 32-разрядные целые числа с прямым порядком байтов со знаком, поэтому 12355 на самом деле 0x00003043. Если вы хотите использовать 16-битные целые числа, используйте тип short.

Затем, чтобы получить отдельные байты в вашем целом числе, вы можете сделать:

bytes[ i ]   = (byte) (someInt >> 24);
bytes[ i+1 ] = (byte) (someInt >> 16);
bytes[ i+2 ] = (byte) (someInt >> 8);
bytes[ i+3 ] = (byte) (someInt);

Преобразование в байт усекает оставшиеся биты, поэтому маска & 0xFF не требуется. Я предполагаю, что i является индексом массива. Чтобы изменить порядок байтов, поменяйте местами смещения индексов.

...