我熟悉InputStream
,缓冲区的概念以及它们为何有用的(例如,当您需要处理可能比机器RAM大的数据时)。 / p>
不过,我想知道InputStream
实际如何携带所有这些数据?如果传输的数据过多,是否会引起OutOfMemoryError
?
如果我从客户端连接到服务器,请求一个100GB的文件,则服务器开始使用缓冲区迭代文件的字节,并使用outputStream.write(byte[])
将字节写回到客户端。无论出于何种原因,客户端现在都不准备读取InputStream
。服务器是否将继续无限期地发送文件的字节?如果是这样,outputstream/inputstream
是否会比其中一台计算机的RAM大?
答案 0 :(得分:5)
InputStream
和OutputStream
实现通常不占用大量内存。实际上,这些类型的“流”一词表示不需要保存数据,因为它是按顺序访问的,就像流可以在两个没有大量水的湖泊和海洋。
但是“流”并不是描述这个词的最好词。这更像管道,因为当您将数据从服务器传输到客户端时,每个阶段都会从客户端传输反压,从而控制数据的发送速率。这类似于水龙头如何控制通过管道一直到城市水库的流量:
InputStream
仅在其内部(较小)缓冲区为空时才向操作系统请求更多数据。每个请求仅允许传输有限数量的数据; OutputStream
时,OutputStream
将尝试将数据写入OS。当OS缓冲区已满时,它将使服务器进程等待,直到服务器端缓冲区有空间接受新数据。请注意,速度较慢的客户端可能会使服务器进程花费很长时间。如果您正在编写服务器,并且不控制客户端,那么考虑这一点并确保在进行长时间的数据传输时不会占用太多服务器端资源非常重要。>
答案 1 :(得分:2)
您的问题既有趣又难以正确回答。
InputStream
和OutputStream
不是存储手段,而是 access 手段:它们描述应按那么,会不会有一个InputStream同时将全部数据存储在内存中?是的,可能会,尽管这将是一个令人震惊的实施。例如,InputStreams / OutputStreams的最常见和最敏感的实现是将少量固定数据存储到4K-8K的临时缓冲区中。
(到目前为止,我想你已经知道了,但是有必要告诉。)
服务器将阻塞多少时间?通常,服务器应具有安全性超时,以确保较长的块会断开连接,从而释放被阻塞的线程。客户端也应该一样。
为连接设置的超时取决于实现方式和协议。
答案 2 :(得分:0)
否,它不需要保存所有数据。我只是在文件中前进(通常使用缓冲的数据)。流可以随意丢弃旧缓冲区。
请注意,输入流的实现方式非常不同,因此确切的行为会有很大的不同。