DataInputStream.read 返回小于 len
我正在使用 DataInputStream 从套接字读取一些字节。我有预期的从流中读取的字节数(解码标头后,我知道消息中有多少字节)它在 99% 的时间内有效,但偶尔我会读取的字节数小于 len。
int numRead = dis.read(buffer, 0, len);
什么可能导致 numRead 小于 len?它不是-1。我希望 read 的行为会阻塞,直到流关闭或达到 EOF,但如果它是流底层的套接字,除非套接字关闭,否则这种情况不会发生,对吧?
有没有一种方法可以从套接字读取字节,并且始终确保读取 len 字节?
谢谢
I am using DataInputStream to read some bytes from a socket. I have a expected number of bytes to read from the stream (after decoding a header, I know how many bytes are in the message) It works 99% of the time but occasionally I will have the number of bytes read be less than len.
int numRead = dis.read(buffer, 0, len);
What could cause numRead to be less than len? It's not -1. I would expect the behavior of read to block until the stream is closed or EOF is reached, but if it's a socket underlying the streams this shouldn't happen unless the socket closes, right?
Is there a way of reading bytes from a socket that will always ensure that you read len bytes?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
编辑:对于一般流,您只需继续阅读,直到读完您想要的所有内容为止。对于
DataInput
的实现(例如DataInputStream
),您应该使用readFully
,正如 Peter Lawrey 所建议的。考虑这个答案的其余部分与您只有一个InputStream
的一般情况相关。任何类型的
InputStream
提供的数据少于您所要求的数据都是完全合理的,即使更多数据正在传输中。您应该始终针对这种可能性进行编码 - ByteArrayInputStream 可能是个例外。 (当然,如果剩余数据少于您要求的数据,那么返回的数据仍然可能少于请求的数据。)这是我正在讨论的循环类型:
EDIT: For a general stream, you just keep reading until you've read everything you want to, basically. For an implementation of
DataInput
(such asDataInputStream
) you should usereadFully
, as suggested by Peter Lawrey. Consider the rest of this answer to be relevant for the general case where you just have anInputStream
.It's entirely reasonable for an
InputStream
of any type to give you less data than you asked for, even if more is on its way. You should always code for this possibility - with the possible exception ofByteArrayInputStream
. (That can still return less data than was requested, of course, if there's less data left than you asked for.)Here's the sort of loop I'm talking about:
您可以通过这种方式使用 DataInputStream。
这将返回所有读取的数据或抛出 IOException。
You can use DataInputStream this way.
This will either return with all the data read or throw an IOException.
read 每次都会返回当时可用的位,完成后返回 -1,您通常应该这样做
read returns each time with the bits that were available at that time and -1 when done, you are typically supposed to do
然后你需要检查Javadocs。 read() 的约定是它将至少读取一个字节,必要时会阻塞,直到读完为止,或者直到 EOS 或发生异常。规范中没有任何内容表明它将读取您请求的整个长度。这就是它返回长度的原因。
Then you need to check the Javadocs. The contract of read() is that it will read at least one byte, blocking if necessary until it has done so, or until EOS or an exception occurs. There is nothing in the specification that says it will read the entire length you requested. That's why it returns a length.
您可以使用 Apache Commons IOUtils,他们有一个方法可以完全满足您的需要:
You can use Apache Commons IOUtils, they have a method that does exactly what you need: