为什么要以块的形式写入Stream?

tig*_*ars 6 c# meta stream point-of-interest

我想知道为什么这么多的例子将字节数组读入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);
}
Run Code Online (Sandbox Code Playgroud)

而不是:

var buffer = new byte[InputStream.Length];

var read = this.InputStream.Read(buffer, 0, buffer.Length);

OutputStream.Write(buffer, 0, read);
Run Code Online (Sandbox Code Playgroud)

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

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

lio*_*ori 20

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

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

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

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


小智 6

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