【问题标题】:Java InputStream.read(byte[], int, int) method, how to block until the exact number of bytes has been readJava InputStream.read(byte[], int, int) 方法,如何阻塞直到读取了确切的字节数
【发布时间】:2011-10-31 04:17:35
【问题描述】:

我正在编写一个简单的客户端/服务器网络应用程序,它通过 TCP 套接字发送和接收固定大小消息。

到目前为止,我一直使用Socket类的getInputStream()getOutputStream()方法来获取流,然后调用InputStream类的read(byte[] b, int off, int len)方法,每次读取60个字节(即消息的大小)。

后来,我阅读了该方法的 Javadoc:

公共 int 读取(字节 [] b, 关闭, 国际化) 抛出 IOException

从输入流中读取最多个字节的数据到一个数组中 字节。尝试读取多达 len 个字节,但更小 可以读取数字。实际读取的字节数返回为 一个整数。

我想知道是否有任何 Java“开箱即用”的解决方案可以阻止,直到读取 len 个字节,如有必要,永远等待。

我显然可以创建一个简单的循环,但我觉得我在重新发明轮子。你能给我推荐一个干净且支持 Java 的解决方案吗?

【问题讨论】:

    标签: java inputstream


    【解决方案1】:

    使用DataInputStream.readFully。它的Javadocs 将读者引导至DataInput Javadocs Javadocs,其中指出:

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

    InputStream in = ...
    DataInputStream dis = new DataInputStream( in );
    byte[] array = ...
    
    dis.readFully( array );
    

    【讨论】:

    • DataInputStream... 一个古老但非常有用的类。这似乎是杀手锏! :P
    • 伙计,我忘记了这个功能,谢谢,为我节省了大量的调试时间!
    • JavaDoc 链接已损坏
    • @ShmilTheCat:谢谢,已修复。
    【解决方案2】:

    我认为棘轮怪胎的正确答案是这样的:

    for (int index = 0; index < toRead && (read = inputStream.read(bytes, index, toRead-index))>0 ; index+= read);
    

    如果 read 返回 -1 则停止读取

    【讨论】:

      【解决方案3】:

      一个简单的单线就可以解决问题

      int toread = 60;
      byte[] buff;
      for(int index=0;index<toread;index+=in.read(buff,index,toread-index));
      

      但大多数情况下,读取字节数减少的唯一原因是流结束或另一侧的字节还没有全部刷新

      【讨论】:

      • 我相信该循环中有一个微妙的错误。如果read 返回-1 会发生什么(如果流过早关闭)?那么这个循环会变成无限循环吗?
      【解决方案4】:

      简单的循环是要走的路。鉴于您要交换的字节数非常少,我想它只需要一次迭代即可读取所有内容,但如果您想让它正确,您必须循环。

      【讨论】:

      • 它让我想起了老式的 unix socket 编程。 :) 我想知道来自 Socket 类的 InputStream 是否真的属于一个“聪明”类......似乎我必须包装 InputStream。
      • DataInputStream 确实有一个 readFully 方法(我忘记了)。看看它的实现:它所做的只是一个简单的循环,直到从其包装的输入流中读取足够的字节。
      • 我明白了。我更喜欢使用 Java API 类,即使是简单的事情,因为我需要我的代码尽可能地可读、可移植和整洁。
      • 当然。您应该使用 readFully。我只是想让你意识到它没有魔法:它所做的只是像你所做的那样循环。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多