为什么要以块的forms写入Stream?

我想知道为什么这么多的例子将字节数组读入chucks中的流而不是一次性…我知道这是一个软问题,但我很感兴趣。

我对硬件和填充缓冲区的理解有点非常依赖,并且你不想再次写入缓冲区,直到它被刷新到需要去的地方等等…但是使用.Net平台(和其他)现代语言)我看到两者的例子。 那么当使用哪个和什么时候,或者是第二个绝对不是没有?

这是我的意思(代码):

var buffer = new byte[4096]; while (true) { var read = this.InputStream.Read(buffer, 0, buffer.Length); if (read == 0) break; OutputStream.Write(buffer, 0, read); } 

而不是:

 var buffer = new byte[InputStream.Length]; var read = this.InputStream.Read(buffer, 0, buffer.Length); OutputStream.Write(buffer, 0, read); 

我相信两者都合法吗? 那么为什么要经历while循环的所有大惊小怪(无论你决定如何构建它)?

我在这里玩恶魔倡导者,因为我想尽可能多地学习:)

在第一种情况下,您只需要4kB的内存。 在第二种情况下,您需要与输入流数据一样多的内存。 如果输入流为4GB,则需要4GB。

如果文件复制操作需要4GB RAM,你认为这会好吗? 如果你要准备一个20GB的磁盘映像怎么办?

管道也有这个东西。 您不经常在Windows上使用它们,但在其他操作系统上经常会出现类似的情况。 第二种情况等待读取所有数据,然后将它们写入输出。 但是,有时建议尽快写入数据 – 第一种情况将在读取第一个4kB输入后立即开始写入输出流。 考虑提供网页:建议Web服务器尽快发送数据,以便客户端的Web浏览器将开始呈现标题和内容的第一部分,而不是等待全身。

但是,如果您知道输入流不会大于4kB,则两种情况都是等效的。

有时,InputStream.Length对某些源无效,例如来自网络传输,或者缓冲区可能很大,例如从大文件中读取。 IMO。

它可以保护您免受输入流长达几千兆字节的情况的影响。

您不知道Read可能会返回多少数据。 如果您正在读取一个非常大的文件,这可能会产生严重的性能问题。

如果您可以控制输入,并且确定大小合理,那么您当然可以立即读取整个数组。 但如果用户可以提供任意输入,请特别小心。