假设我们在两个设备(a和b)之间有一个套接字连接。现在,如果我只向a侧套接字的输出流(不是bufferedoutputstream)写入16个字节(大小在这里无关紧要),则会这样写3次或多次:
OutputStream outputStream = socket.getOutputStream();
byte[] buffer = new byte[16];
OutputStream.write(buffer);
OutputStream.write(buffer);
OutputStream.write(buffer);
我使用套接字输入流(不是bufferedinputstream)读取b侧的数据,其缓冲区大于发送缓冲区,例如1024:
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int read = inputStream.read(buffer);
现在我想知道b面是如何接收数据的?它可能会被积累起来,或者它会在数据发送时准确地读取数据?换句话说,read变量可能超过16?
2条答案
按热度按时间uqzxnwby1#
InputStream
对于多字节的任何调用将读取多少数据,很少有保证read()
方法。有一整类常见的编程错误围绕着误解和错误的假设。例如,如果
InputStream.read(byte[])
读取的字节数少于提供的数组所能容纳的字节数,这并不意味着已到达流的结尾,甚至不意味着另一次读取必然会阻塞。任何一次调用所读取的字节数
InputStream.read(byte[])
不一定与流所绘制的字节源的任何特征相关,只是当它不在流的末尾时,它总是至少读取一个字节,并且它读取的字节不会超过它返回时实际可用的字节。所指示的可用字节数
available()
方法不能可靠地指示后续读取应该或将要读取多少字节。非零返回值可靠地表示下一次读取不会阻塞;一个零返回值告诉你什么都没有。子类可以保证其中的一些行为,但大多数都没有,而且您通常不知道您实际拥有哪个子类。
为了使用
InputStream
通常,您必须准备好执行重复读取,直到获得足够的数据进行处理。这可能意味着在积累特定数量的字节之前一直读取,或者在遇到分隔符之前一直读取。在某些情况下,您可以处理任何给定读取的任何字节数;一般来说,这些情况下,你是无论如何循环,并提供一切你读到的消费者,可以接受可变长度块(许多压缩和加密接口是这样的,例如)。z9smfwbn2#
根据文件:
从输入流中读取一定数量的字节,并将它们存储到缓冲区数组b中。实际读取的字节数以整数形式返回。此方法会一直阻塞,直到输入数据可用、检测到文件结尾或引发异常为止。如果b的长度为零,则不读取字节,返回0;否则,将尝试读取至少一个字节。如果由于流位于文件末尾而没有字节可用,则返回值-1;否则,至少有一个字节被读取并存储到b中。
读取的第一个字节存储在元素b[0]中,下一个字节存储在元素b[1]中,依此类推。读取的字节数最多等于b的长度。设k为实际读取的字节数;这些字节将存储在元素b[0]到b[k-1]中,而元素b[k]到b[b.length-1]不受影响。
Read(...)
告诉您它放入数组的字节数,是的,您可以进一步读取;你会得到已经在那里的东西。