javasocket读取的数据和发送的数据完全一样吗

um6iljoc  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(256)

假设我们在两个设备(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?

uqzxnwby

uqzxnwby1#

InputStream 对于多字节的任何调用将读取多少数据,很少有保证 read() 方法。有一整类常见的编程错误围绕着误解和错误的假设。例如,
如果 InputStream.read(byte[]) 读取的字节数少于提供的数组所能容纳的字节数,这并不意味着已到达流的结尾,甚至不意味着另一次读取必然会阻塞。
任何一次调用所读取的字节数 InputStream.read(byte[]) 不一定与流所绘制的字节源的任何特征相关,只是当它不在流的末尾时,它总是至少读取一个字节,并且它读取的字节不会超过它返回时实际可用的字节。
所指示的可用字节数 available() 方法不能可靠地指示后续读取应该或将要读取多少字节。非零返回值可靠地表示下一次读取不会阻塞;一个零返回值告诉你什么都没有。
子类可以保证其中的一些行为,但大多数都没有,而且您通常不知道您实际拥有哪个子类。
为了使用 InputStream 通常,您必须准备好执行重复读取,直到获得足够的数据进行处理。这可能意味着在积累特定数量的字节之前一直读取,或者在遇到分隔符之前一直读取。在某些情况下,您可以处理任何给定读取的任何字节数;一般来说,这些情况下,你是无论如何循环,并提供一切你读到的消费者,可以接受可变长度块(许多压缩和加密接口是这样的,例如)。

z9smfwbn

z9smfwbn2#

根据文件:

public int read(byte[] b) throws IOException

从输入流中读取一定数量的字节,并将它们存储到缓冲区数组b中。实际读取的字节数以整数形式返回。此方法会一直阻塞,直到输入数据可用、检测到文件结尾或引发异常为止。如果b的长度为零,则不读取字节,返回0;否则,将尝试读取至少一个字节。如果由于流位于文件末尾而没有字节可用,则返回值-1;否则,至少有一个字节被读取并存储到b中。
读取的第一个字节存储在元素b[0]中,下一个字节存储在元素b[1]中,依此类推。读取的字节数最多等于b的长度。设k为实际读取的字节数;这些字节将存储在元素b[0]到b[k-1]中,而元素b[k]到b[b.length-1]不受影响。 Read(...) 告诉您它放入数组的字节数,是的,您可以进一步读取;你会得到已经在那里的东西。

相关问题