La mejor forma actual de completar una matriz de bytes de tipo mixto

I'm trying to send and receive a byte stream in which certain ranges of bytes represent different pieces of data. I've found ways to convert single primitive datatypes into bytes, but I'm wondering if there's a straightforward way to place certain pieces of data into specified byte regions.

For example, I might need to produce or read something like the following:

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

Cualquier sugerencia sera apreciada.

preguntado el 01 de febrero de 12 a las 22:02

I've given an answer for the normal size of the integers and doubles. You may store the integer in a ByteBuffer and retrieve the last #size of bytes (of the 4) if you want to downsize, checking that the first bytes are indeed zero, or you will loose data. This will be harder for doubles, you might have to create your own format if you want to downsize, loosing precission in the process. -

I finally was able to convince the spec providers to restrict data lengths to corresponding Java primitives, making this much easier. We ran into the problem that they wanted to use 2-byte floating point, which didn't map to any operations in the ByteBuffer and we decided it was easier to get them to change than to try and support it on our side. -

2 Respuestas

Trata DataOutputStream/DataInputStream or, for arrays, the ByteBuffer clase.

For storing the integer in X bytes, you may use the following method. If you think it is badly named, you may use the much less descriptive i2os name which is used in several (crypto) algorithm descriptions. Note that the returned octet string uses Big Endian encoding of unsigned ints, which you should specify for your protocol.

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);

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

    // less bytes than long encoding (reset to mark first)
    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];
    return result;

EDIT before storing the string, think of a padding mechanism (spaces would be most used), and character-encoding e.g. String.getBytes(Charset.forName("ASCII")) or "Latin-1". Those are the most common encodings with a single byte per character. Calculating the size of "UTF-8" is slightly more difficult (encode first, add 0x20 valued bytes at the end using ByteBuffer).

Respondido 02 Feb 12, 03:02

You may want to consider having a constant size for each data type. For example, the 32-bit Java int will take up 4 bytes a long will take 8, etc. In fact, if you use Java's DataInputStream and DataOutputStreams, you'll basically be doing that anyway. They have really nice methods like read/writeInt, etc.

Respondido 02 Feb 12, 02:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.