我有一个Java类
public class MsgLayout{
int field1;
String field2;
long field3;
}
我必须将此对象写为Socket输出流中的字节数组。三个字段(实例变量)具有布局。即field1
必须占用1个字节,field2
必须占用4个字节,field3
必须占用8个字节。
ByteBuffer bbf = ByteBuffer.allocate(TOTAL_SIZE);
bbf.put(Integer.toString(this.getField1()).getBytes(), 0, FIELD1_SIZE);
bbf.position(FIELD2_OFFSET);
bbf.put(Long.toString(this.getField2()).getBytes(), 0, FIELD2_SIZE);
bbf.position(FIELD3_OFFSET);
bbf.put(Long.toString(this.getField3()).getBytes(), 0, FIELD3_SIZE);
byte[] msg = bbf.array();
使用上面的代码,我试图根据所需的大小调整字节数组中的每个字段。但是我得到IndexOutOfBoundException
简而言之,问题在于如何使字段符合布局定义的大小。例如FIELD1_OFFSET = 0, FIELD1_SIZE=1, FIELD2_OFFSET=1, FIELD2_SIZE=4, FIELD3_OFFSET=5, FIELD3_SIZE=8.
现在当我将field1
转换为String时,转换为byte []时它不适合1个字节。如果我没有转换为String,并使用putInt(int),它会将4个字节写入生成的字节数组。
答案 0 :(得分:2)
您的代码目前正在做的是将数字字段编码为字符串,然后输出这些字符的字节。
我建议使用DataOutputStream类来包装你的SocketOutput流并写下你的二进制数据:
DataOutput output = new DataOutputStream(socketOutputStream);
int field1 = 1;
String field2 = "Hello";
long field3 = 5000000000L;
output.writeByte(field1);
output.writeBytes(field2.substring(0, 3));
output.writeLong(field3);
此代码中有几个假设。首先,我假设对于字段2,您希望将4个字符序列化为每个字节。如果你想使用像UTF-8这样的任何多字节编码,那么你需要做一些不同的事情。其次,我假设字段2总是至少有4个字符。
答案 1 :(得分:0)
field1
可能只有一个字节的数据,但其字符串表示形式将是一个或多个字符(例如"0"
,"63"
,"127"
)。 String中的每个字符实际上都是char
(两个字节的值)。因此,当通过byte-> String-> byte []转换时,我希望一个字节的数据膨胀为2到6个字节的数据。