6

我想知道为什么这么多示例将字节数组读入卡盘中的流中,而不是一次全部读入......我知道这是一个软问题,但我很感兴趣。

我了解一些关于硬件和填充缓冲区的信息可能非常依赖于大小,并且您不想再次写入缓冲区,直到它被刷新到它需要去的任何地方等等......但是使用.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 循环的所有大惊小怪(无论您决定如何构建它)?

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

4

4 回答 4

20

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

您认为如果文件复制操作需要 4GB 内存会更好吗?如果您要准备一个 20GB 的磁盘映像怎么办?

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

但是,如果您知道输入流不会大于 4kB,那么这两种情况是等价的。

于 2012-11-28T14:24:33.487 回答
6

有时,InputStream.Length 对某些源无效,例如来自网络传输,或者缓冲区可能很大,例如从一个巨大的文件中读取。国际海事组织。

于 2012-11-28T14:25:26.697 回答
2

它可以保护您免受输入流为数 GB 长的情况。

于 2012-11-28T14:24:04.497 回答
2

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

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

于 2012-11-28T14:24:25.947 回答