gpt4 book ai didi

java - 如何在 Java 中表示位字段(并发送它们)

转载 作者:行者123 更新时间:2023-12-01 04:34:20 25 4
gpt4 key购买 nike

在我当前的项目中,我需要通过网络发送一个包含一些 n 位字段的解析结构。例如:

  • 协议(protocol)版本:1字节
  • messageId:1字节
  • 创建时间:6字节
  • traceId:3 位
  • 可靠性:7 位
  • 等等...

因此,我创建了一个简单的 POJO 类来表示解析和解解析,但我对这些字段使用什么类型有一些疑问,因为这个决定可以使解析和解解析变得容易或有点噩梦。我必须说,通过网络发送的消息有一个非常具体的大小限制:它不能超过所有字段的总和。

我首先尝试使用字节来处理所有内容,然后使用 Message.getBytes() 方法来转换消息,对于那些小于字节的字段,使用按位运算来丢弃不必要的位。

我的方向是正确的还是有另一种更简单的方法来做到这一点?我只是觉得我在这里重新发明轮子,这感觉有点样板代码......

谢谢!

编辑:如果其他人在这里遇到困难,我会发布我如何解决这个问题(感谢工作中的同事帮助我解决这些问题),所以请继续阅读:

幸运的是,我的协议(protocol)套接字大小四舍五入到固定的字节数 (49),并且那些小于字节大小的字段在最后总结一个字节,这样我就可以将这两个字段合并在一个字节中字节优先解析/解解析。

也就是说,假设我有两个字段,即 field1 和 field2,第一个字段为 7 位,另一个字段为 1 位。为了将这些结合起来,我只需执行以下技巧:

byte resultingByte = short2Byte((short) ((field1 % 128) * 2 + (field2 ? 1 : 0)));

请注意,field1 和 field2 都是短类型。我发现这是在位级别工作的最方便的方法。因此,我对第一个字段进行修改,确保只获得 7 位,将这些位向左移动 2,因为只需要移动一位。最后,我添加了字段 2 Short,它可以是 1 或 0。然后我在 8 个低有效位中添加了包含所需值的 Short。

我创建了从 Short2Byte、Long 和其他一些方法进行转换的商品方法:

private byte [] to2Bytes(int in) {
ByteBuffer ret = ByteBuffer.allocate(2);
int val = in % 65536;

short s1 = (short) (val / 256);
short s0 = (short) (val % 256);

ret.put(short2Byte(s1));
ret.put(short2Byte(s0));

return ret.array();
}

private byte [] to4Bytes(long in) {
ByteBuffer ret = ByteBuffer.allocate(4);
long div = 4294967296L;
long val = in % div;
int rem = 0;

short s3 = (short) (val / 16777216L);
rem = (int) (val % 16777216L);
short s2 = (short) (rem / 65536);
rem = rem % 65536;
short s1 = (short) (rem / 256);
short s0 = (short) (rem % 256);

ret.put(short2Byte(s3));
ret.put(short2Byte(s2));
ret.put(short2Byte(s1));
ret.put(short2Byte(s0));

return ret.array();
}

private byte [] time2Bytes(Long time) {
ByteBuffer ret = ByteBuffer.allocate(6);
String hex = Long.toHexString(time).toUpperCase();
while (hex.length() < 12) {
hex = "0" + hex;
}

while (hex.length() > 12) {
hex = hex.substring(1);
}

try {
for (int i = 0; i < 6; i++) {
String strByte = "" + hex.charAt(i*2) + hex.charAt(i*2 + 1);
short b = Short.parseShort(strByte, 16);
if (b > 127) {
b -= 256;
}
ret.put((byte) b);
}
}
catch (NumberFormatException e) {
// Exception captured for correctness
e.printStackTrace();
}


return ret.array();
}

private long bytes2time(byte b5, byte b4, byte b3, byte b2, byte b1, byte b0) {
long l5, l4, l3, l2, l1, l0;
l5 = byte2short(b5) * 1099511627776L;
l4 = byte2short(b4) * 4294967296L;
l3 = byte2short(b3) * 16777216L;
l2 = byte2short(b2) * 65536L;
l1 = byte2short(b1) * 256L;
l0 = byte2short(b0) * 1L;
return l5 + l4 + l3 + l2 + l1 + l0;
}

private long bytes2long(byte b3, byte b2, byte b1, byte b0) {
long l3, l2, l1, l0;
l3 = byte2short(b3) * 16777216L;
l2 = byte2short(b2) * 65536L;
l1 = byte2short(b1) * 256L;
l0 = byte2short(b0) * 1L;
return l3 + l2 + l1 + l0;
}

private int bytes2int(byte b1, byte b0) {
return (int)byte2short(b1) * 256 + (int)byte2short(b0);
}

private short byte2short(byte b) {
if (b < 0) {
return (short) (b+256);
}
return (short)b;
}

private byte short2Byte(short s) {
if (s < 128) {
return (byte) s;
}
else {
return (byte) (s-256);
}
}

最后我发送了一个 49 字节的字节数组。显然,解析是非常相似的过程。必须有一个正确的方法来做到这一点,但是,它有效......希望这对某人有帮助!

最佳答案

您可以使用ByteBufferBitSet类来写入和读取消息,但它仍然可能成为一场噩梦,甚至比纯位操作更糟糕(并且会影响性​​能)

关于java - 如何在 Java 中表示位字段(并发送它们),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17545601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com