Текущий лучший способ заполнить массив байтов смешанного типа - PullRequest
0 голосов
/ 02 февраля 2012

Я пытаюсь отправить и получить поток байтов, в котором определенные диапазоны байтов представляют разные фрагменты данных.Я нашел способы преобразования отдельных примитивных типов данных в байты, но мне интересно, есть ли простой способ поместить определенные фрагменты данных в указанные байтовые области.что-то вроде следующего:

byte 1 - int
byte 2-5 - int
byte 6-13 - double
byte 14-21 - double
byte 25 - int
byte 26-45 - string

Любые предложения будут оценены.

Ответы [ 2 ]

1 голос
/ 02 февраля 2012

Попробуйте DataOutputStream / DataInputStream или, для массивов, ByteBuffer класс.

Для хранения целого числа в байтах X вы можетеиспользуйте следующий метод.Если вы думаете, что оно имеет неправильное имя, вы можете использовать гораздо менее описательное имя i2os, которое используется в нескольких (крипто) описаниях алгоритмов.Обратите внимание, что возвращаемая строка октетов использует кодировку Big Endian беззнаковых целых чисел, которую вы должны указать для своего протокола.

public static byte[] possitiveIntegerToOctetString(
        final long value, final int octets) {
    if (value < 0) {
        throw new IllegalArgumentException("Cannot encode negative values");
    }

    if (octets < 1) {
        throw new IllegalArgumentException("Cannot encode a number in negative or zero octets");
    }

    final int longSizeBytes = Long.SIZE / Byte.SIZE;
    final int byteBufferSize = Math.max(octets, longSizeBytes);
    final ByteBuffer buf = ByteBuffer.allocate(byteBufferSize);
    for (int i = 0; i < byteBufferSize - longSizeBytes; i++) {
        buf.put((byte) 0x00);
    }
    buf.mark();
    buf.putLong(value);

    // more bytes than long encoding
    if (octets >= longSizeBytes) {
        return buf.array();
    }

    // less bytes than long encoding (reset to mark first)
    buf.reset();
    for (int i = 0; i < longSizeBytes - octets; i++) {
        if (buf.get() != 0x00) {
            throw new IllegalArgumentException("Value does not fit in " + octets +  " octet(s)");
        }
    }

    final byte[] result = new byte[octets];
    buf.get(result);
    return result;
}

РЕДАКТИРОВАТЬ перед сохранением строки, подумайте о механизме заполнения (пробелы были бы наиболее использованы),и кодировка символов, например String.getBytes(Charset.forName("ASCII")) или "Latin-1".Это наиболее распространенные кодировки с одним байтом на символ.Вычислить размер «UTF-8» немного сложнее (сначала закодируйте, добавьте 0x20 байтов в конце, используя ByteBuffer).

0 голосов
/ 02 февраля 2012

Возможно, вы захотите иметь постоянный размер для каждого типа данных.Например, 32-битный Java int будет занимать 4 байта, длинный - 8 и т. Д. Фактически, если вы используете Java DataInputStream и DataOutputStreams, вы в любом случае будете это делать.У них действительно хорошие методы, такие как read / writeInt и т. Д.

...