【问题标题】:DataInputStream.read() vs DataInputStream.readFully()DataInputStream.read() 与 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() 当缓冲区被填满时。

标签: java sockets java-io


【解决方案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()
    猜你喜欢
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多