Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中查找2字节的值_Java_Byte - Fatal编程技术网

在Java中查找2字节的值

在Java中查找2字节的值,java,byte,Java,Byte,我试图找到UDP数据包中前2个字节的值,该值对应于剩余有效负载的长度。如果我知道前2个字节,那么在Java中找到这个值的最佳方法是什么?java.nio.ByteBuffer有什么用处吗 谢谢我通常用这样的东西: static public int buildShort(byte high, byte low) { return ((0xFF & (int) high) * 256) + ((0xFF & (int) low)); } 然后获取数据包的前两个字节: int

我试图找到UDP数据包中前2个字节的值,该值对应于剩余有效负载的长度。如果我知道前2个字节,那么在Java中找到这个值的最佳方法是什么?
java.nio.ByteBuffer
有什么用处吗


谢谢

我通常用这样的东西:

static public int buildShort(byte high, byte low)
{
  return ((0xFF & (int) high) * 256) + ((0xFF & (int) low));
}
然后获取
数据包的前两个字节:

int length = buildShort(packet.getData()[0], packet.getData()[1]);

请注意,我使用length作为
int
,因为
short
数据类型(因为每个人)都是用Java签名的,所以需要更大的空间。

只有在读取UDP数据包(使用nio)时,使用ByteBuffer才有价值。您可以创建一个实用程序方法:

static final int getLength(DatagramPacket packet) {
 byte data[] = DatagramPacket.getData();
 return (int)((0xFF & (int)data[0]) << 8) | (0xFF & (int)data[1]));
}
static final int getLength(DatagramPacket数据包){
字节数据[]=DatagramPacket.getData();

return(int)((0xFF&(int)data[0])您确实可以使用
java.nio.ByteBuffer

ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.put(byte1);
buffer.put(byte2);
int length = buffer.getShort(0) & 0xFFFF; // Get rid of sign.

使用
ByteBuffer
很方便,只是不要被Java签名的16位值绊倒:

byte[] data = new byte[MAX_LEN];
ByteBuffer buf = ByteBuffer.wrap(data);
DatagramPacket pkt = new DatagramPacket(data, data.length);
⋮    
while (connected) {
  socket.receive(pkt);
  int len = buf.getShort() & 0xFFFF;
  ⋮
}
如果您不想使用
ByteBuffer
,转换仍然相当简单。可以使用等效的乘法和加法,但我看到位运算符使用得更频繁:

int len = (data[0] & 0xFF) << 8 | data[1] & 0xFF;

int len=(数据[0]&0xFF)您正在尝试从两个8位整数中获取16位整数吗?文档仅说明有效负载长度在前2个字节中。可能只是一个16位整数,而不是添加两个8位整数。对于这样一个简单的问题进行了史诗般的讨论。这确实使您能够在网络和windows字节顺序之间切换,但代价是对象分配(以及一些额外的逻辑)此外,如果使用2字节长度,则应向上转换为int(),以消除符号(
((int)buffer.getShort(0))| 0xFFFF
)@贾斯汀:你说得对。你希望以无符号值结束。ByteBuffer非常支持将字节数组解释为各种基本类型,包括支持大尾端和小尾端。没错,这里有一个折衷:你在交易分配成本(以及随后的垃圾收集)ByteBuffer与数据[0]和数据[1]的2范围检查内存访问成本的比较。除非您将ByteBuffer用作DatagramChannel的读取源,否则我认为这不会有回报。全部
(int)
cast是多余的。否则,这是一种方式。人们对他们的答案非常固执。你的答案很好,除了第一句话,这很糟糕。的确,使用ByteBuffer可能会稍微慢一点,但两者本质上是一样的。我的意思是,Java不是关于微优化和“回报”不是CPU周期而是程序员周期。你可能会说你的解决方案比引入像ByteBuffer这样模糊的东西更清晰,这是一个公平的论点。我的经验是,ByteBuffers为将字节数组转换成各种java整数的问题增加了一致性和清晰性。+1用于识别顽固性,尽管“pro”Grammar cycles’可以有多种含义:对于ByteBuffer,我们引入了对nio的依赖,这意味着我们不是1.4可移植的,我们想要一个无符号的结果,但ByteBuffer不提供它,我们引入了一个用于一个目的的类(I/O缓冲区)这实际上被用作读取一个int的实用方法。我更喜欢Justin和erickson的风格,例如,“是的,运算符在性能上没有任何差异(因为JIT将自己用位运算符来完成优化这一点的脏活)…这只是品味的问题:)@Dimitris:嗯,我不同意:你真正做的是乘法和加法,将一个base-256编码的整数转换成一个java整数。这只是幸运的巧合,编码基数是二的幂。当然,不太幸运,这样做是为了提高效率。所以我想我们都是对的。