Java NIO:读取可变大小的块

发布于 2024-08-02 13:01:21 字数 428 浏览 5 评论 0原文

我想从 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() 调用读取过去缓冲区中的数据:-(

我可能需要翻转、倒带的某种组合,重置等等,但我无法弄清楚。

I would like to read a string from a TCP stream that is given with a byte length followed by the actual data. In Python, I would do

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

How do I do the same in Java NIO? What I have is a buffer (of capacity 257)

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

Unfortunately, this doesn't work: the get() calls read past the data in the buffer :-(

I probably need some combination of flip, rewind, reset, etc., but I can't figure it out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野稚 2024-08-09 13:01:21

如果 streamSocketChannel 并且 bufferByteBuffer,您可以执行以下操作:

//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

if stream is a SocketChannel and buffer is a ByteBuffer, you can do the following:

//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
香橙ぽ 2024-08-09 13:01:21

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

这就是您通过 Python 示例所做的事情(第一个字节表示有效负载长度,使用该长度读取播放负载),这看起来确实很容易出错(!)。

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

I suggest, you have a look into java.nio.channel.GatheringByteChannel and DatagramChannel. You'll need to specifiy a Datagram for your needs.

That's what you've done by your Python example (first byte indicates the payload length, read the playload using this length), which looks really fault-prone(!).

A datagram is a specification for a data stream. It divides your stream into packages, logically. So, a better strategy would be to send a payload-package first, that indicates the length of the payload (and the package size). Edit: Of course, both sides of the stream must speak the same protocol / datagram language.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文