DataInputStream.read() 与 DataInputStream.readFully()

Posted

技术标签:

【中文标题】DataInputStream.read() 与 DataInputStream.readFully()【英文标题】:DataInputStream.read() vs DataInputStream.readFully() 【发布时间】:2014-11-11 21:45:06 【问题描述】:

我正在制作一个简单的 TCP/IP Socket 应用程序

这样做有什么不同:

DataInputStream in = new DataInputStream(clientSocket.getInputStream());

byte[] buffer = new byte[100];
in.readFully(buffer);

相对于这样做:

DataInputStream in = new DataInputStream(clientSocket.getInputStream());

byte[] buffer = new byte[100];
in.read(buffer);

我查看了文档,它们的描述完全相同。 readFully()read() 那么我可以假设它是同一件事吗?

【问题讨论】:

你想如何处理 EOF(意味着当套接字上没有更多字节要读取时)?再次查看两者的定义,而不仅仅是描述。一个返回值,一个抛出异常。 @scrappedcola 哦,好的,我现在明白了。所以基本上,readFully() 在缓冲区已满时返回,无论是否还有更多字节要读取。当所有字节都被读取时,read() 返回。对吗? 没有。 read() 至少读取一个字节时返回; readFully() 当缓冲区被填满时。 【参考方案1】:

使用 read 您需要检查返回值以了解实际读取了多少字节

byte[] buffer = new byte[100];
if (in.read(buffer) < 100)
   // fail
   

readFully如果无法读取100字节会抛出IOException,不需要检查返回值,稍微简化一下。

【讨论】:

【参考方案2】:

DataInput.readFully(byte[] b) 的 Javadoc 声明:

从输入流中读取一些字节并将它们存储到缓冲区中 数组b读取的字节数等于b的长度

DataInputStream.read(byte[] b) 的 Javadoc 声明:

从包含的输入流中读取一些字节并存储 将它们放入缓冲区数组b实际读取的字节数为 作为整数返回。此方法阻塞,直到输入数据 可用,检测到文件结尾,或抛出异常

基本上,readFully() 将读取 精确 b.length 字节,而 read() 将读取 最多 b.length,可能更少,无论从输入流。

【讨论】:

完美,这就是我的想法。感谢您的澄清 我可能会补充一点,readFully()基于网络的操作中更好。在发送长消息(例如,缓冲区 超过 5K 字节)时,我自己只遇到了 read() 的麻烦。仅使用 read() 时,部分消息丢失并替换为 ? 字符。使用readFully() 解决了我的问题:阅读了完整的消息,根本没有丢失任何字符。 ;-) 希望能帮助到你 ! ;-) 如果我必须在超时后中断 readFully() 方法? @Mackovich 它没有被 ?人物。它们是缓冲区中超出读取内容的剩余内容。 read() 返回的计数不包括它们。 @user2602807 您设置了套接字读取超时。但是如果超时触发,您将丢失任何已读取的数据,或者您将不知道读取了多少数据(如果有的话)。最好在超时时使用read()

以上是关于DataInputStream.read() 与 DataInputStream.readFully()的主要内容,如果未能解决你的问题,请参考以下文章

python网络编程基础(线程与进程并行与并发同步与异步)

=与==&与&&| 与 || 的区别

与 0 进行比较与与某个值进行比较是不是更快?

三.工具与市场-债券与债务股票与公司

RESTfulREST 与 RESTful 理解与实践

RESTfulREST 与 RESTful 理解与实践