我正在尝试发送和接收字节流,其中某些字节范围代表不同的数据片段。我已经找到了将单个原始数据类型转换为字节的方法,但我想知道是否有一种直接的方法将某些数据放入指定的字节区域。
例如,我可能需要制作或阅读以下内容:
byte 1 - int
byte 2-5 - int
byte 6-13 - double
byte 14-21 - double
byte 25 - int
byte 26-45 - string
任何建议都将不胜感激。
答案 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等。