我想知道为什么这么多的例子将字节数组读入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循环的所有大惊小怪(无论你决定如何构建它)?
我在这里扮演魔鬼,因为我想尽可能多地学习:)
答案 0 :(得分:20)
在第一种情况下,您只需要4kB的内存。在第二种情况下,您需要与输入流数据一样多的内存。如果输入流是4GB,则需要4GB。
你认为文件复制操作需要4GB RAM会不会很好?如果你要准备一个20GB的磁盘映像怎么办?
管道也有这个东西。您不经常在Windows上使用它们,但在其他操作系统上经常会出现类似的情况。第二种情况等待读取所有数据,然后将它们写入输出。但是,有时建议尽快写入数据 - 第一种情况将在读取第一个4kB输入后立即开始写入输出流。考虑提供网页:建议Web服务器尽快发送数据,以便客户端的Web浏览器开始呈现标题和内容的第一部分,而不是等待全身。
但是,如果你知道输入流不会大于4kB,那么两种情况都是等价的。
答案 1 :(得分:6)
有时,InputStream.Length对某些来源无效,例如来自网络传输,或者缓冲区可能很大,例如从一个巨大的文件中读取。 IMO。
答案 2 :(得分:2)
它可以保护您免受输入流长达几千兆字节的情况的影响。
答案 3 :(得分:2)
您不知道有多少数据Read
可能会返回。如果您正在阅读非常大的文件,这可能会产生严重的性能问题。
如果您可以控制输入,并且确定大小合理,那么您当然可以立即读取整个数组。但如果用户可以提供任意输入,请特别小心。