当前填充混合类型字节数组的最佳方法

时间:2012-02-01 22:12:15

标签: java bytearray

我正在尝试发送和接收字节流,其中某些字节范围代表不同的数据片段。我已经找到了将单个原始数据类型转换为字节的方法,但我想知道是否有一种直接的方法将某些数据放入指定的字节区域。

例如,我可能需要制作或阅读以下内容:

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

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:1)

尝试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”的大小稍微困难一些(先编码,最后使用ByteBuffer添加0x20值的字节)。

答案 1 :(得分:0)

您可能需要考虑为每种数据类型设置一个常量。例如,32位Java int将占用4个字节,一个长度需要8个等等。事实上,如果你使用Java的DataInputStream和DataOutputStreams,你基本上都会这样做。他们有非常好的方法,如read / writeInt等。