Java NIO:读取可变大小的块

时间:2009-08-22 20:08:40

标签: java buffer nio

我想从TCP流中读取一个字符串,该字符串长度后跟实际数据。在Python中,我会做

length = ord(stream.read(1))
data = stream.read(length)

我如何在Java NIO中做同样的事情?我所拥有的是缓冲区(容量257)

stream.read(buffer); // cannot specify a size here
int length = buffer.get();
byte[] data = new byte[length];
buffer.get(data);

不幸的是,这不起作用:get()调用读取过去缓冲区中的数据: - (

我可能需要翻转,倒带,重置等组合,但我无法理解。

2 个答案:

答案 0 :(得分:5)

如果streamSocketChannelbufferByteBuffer,您可以执行以下操作:

//assuming buffer is a ByteBuffer
buffer.position(0);
buffer.limit(1);
while (buffer.hasRemaining()) { 
   stream.read(buffer);
}
buffer.rewind();

//get the byte and cast it into the range 0-255
int length = buffer.get() & 0xFF;
buffer.clear();
buffer.limit(length);
while (buffer.hasRemaining()) { 
   stream.read(buffer);
}
buffer.rewind();
//the buffer is now ready for reading the data from

答案 1 :(得分:0)

我建议你看一下java.nio.channel.GatheringByteChannel和DatagramChannel。您需要根据需要指定数据报。

这就是你的Python示例所做的(第一个字节表示有效负载长度,使用此长度读取playload),这看起来非常容易出错(!)。

数据报是数据流的规范。它逻辑上将您的流划分为包。因此,更好的策略是首先发送有效负载包,指示有效负载的长度(以及包大小)。编辑:当然,流的两端必须使用相同的协议/数据报语言。