我试图发送和接收字节流,其中某些字节范围表示不同的数据片段。我已经找到了将单个原始数据类型转换为字节的方法,但是我想知道是否有一种直接的方式将某些数据片段放入指定的字节区域。当前填充混合类型字节数组的最佳方式
例如,我可能需要产生或读一些类似如下:
byte 1 - int
byte 2-5 - int
byte 6-13 - double
byte 14-21 - double
byte 25 - int
byte 26-45 - string
任何建议,将不胜感激。
我试图发送和接收字节流,其中某些字节范围表示不同的数据片段。我已经找到了将单个原始数据类型转换为字节的方法,但是我想知道是否有一种直接的方式将某些数据片段放入指定的字节区域。当前填充混合类型字节数组的最佳方式
例如,我可能需要产生或读一些类似如下:
byte 1 - int
byte 2-5 - int
byte 6-13 - double
byte 14-21 - double
byte 25 - int
byte 26-45 - string
任何建议,将不胜感激。
尝试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值字节)。
您可能需要考虑每种数据类型都有一个固定的大小。例如,32位Java int将占用4个字节,长度将占用8个,等等。实际上,如果您使用Java的DataInputStream和DataOutputStreams,那么您基本上会这样做。他们有非常好的方法,如读/写等。
我已经给出了正常大小的整数和双打的答案。您可以将整数存储在ByteBuffer中,如果要缩小大小,检查最后一个大小的字节(大小为4),检查第一个字节确实为零,否则将丢失数据。这对于双打来说会更困难,如果你想缩小尺寸,那么你可能必须创建自己的格式。 – 2012-02-01 22:29:16
我终于可以说服规范提供者将数据长度限制为相应的Java原语,这使得这更容易。我们遇到了他们想要使用2字节浮点的问题,该浮点并没有映射到ByteBuffer中的任何操作,我们认为让他们改变比在我们这边尝试和支持它更容易。 – 2012-02-17 22:53:29