C#中缓冲区和流的区别

26
我了解到 Buffer 是一系列字节,而 Stream 也是一系列字节。那么 Stream 和 Buffer 有什么区别呢?

1
缓冲区具有指定的确定长度,而流则没有。 - ThePerplexedOne
4
流是读取或写入的字节序列,而缓冲区是存储的字节序列。 - Abion47
1
@Abion47,正如您所说,缓冲区的目的是存储字节序列,那么我的问题是流不存储在内存中吗? - Neel Maheta
1
@neelmaheta 一个流本身并不存储任何东西。它只是作为一个通道,将数据从一个点移动到另一个点。 - Abion47
谢谢,我读了你关于网络流的例子。明白了流实际上是什么。再次感谢。 - Neel Maheta
@Abion47 我也读到了流(stream)有其内部缓冲区。那么内部缓冲区的用途是什么,应该在哪里使用呢?谢谢。 - Neel Maheta
2个回答

29
正如我在评论中所说,缓冲区和流之间的简要区别在于,流是从指定源传输信息的序列,而缓冲区是存储在内存中的字节序列。例如:
FileStream stream = new FileStream("filepath.txt", FileMode.OpenOrCreate);

打开一个文件流。该流可以被读取、写入或两者兼备。由于不需要额外的内存,因此它轻巧且快速,但是任意引用源中特定数据集可能很麻烦。流也受益于作为连接而不是离散数据集,因此您不需要预先知道数据的大小。
相反:
byte[] fileContents = File.ReadAllBytes("filepath.txt");

将文件的所有字节读入内存。当您需要一次性操作整个文件或保留“本地副本”以便程序可以持有文件并使其可用于其他用途时,这非常方便。但是,根据源代码的大小和可用内存的数量,包含整个文件的缓冲区可能不是一个选择。
然而,这只是一个基本解释。还有更详细的解释。例如,正如Marc Gravell所说:
许多数据结构(如列表、集合等)用作容器--它们保存一组对象。但流不是容器,如果列表是水桶,那么流就是软管。您可以从流中提取数据或将数据推入流中--但通常只能在一个方向上进行一次(当然有例外)。例如,通过网络传输的TCP数据就是一种流;您可以发送(或接收)数据块,但只与其他计算机连接一次,并且通常只能这样做一次--您无法倒回互联网。
流也可以操作通过它们传递的数据;压缩流、加密流等。但再次强调--这里的基本隐喻是数据的软管。文件通常也被视为流来访问(在某个层面上);您可以访问连续数据块。当然,大多数文件系统也提供随机访问,因此流确实提供诸如搜索、位置、长度等功能--但并非所有实现都支持这些功能。在某些流中寻找或获取打开套接字的长度是没有意义的。

我也读到了流有其内部缓冲区。那么内部缓冲区的用途是什么,何时使用它? - Neel Maheta
@neelmaheta 一般来说,流没有内部缓冲区。_特定类型的流_有时会有,例如BufferedStreamMemoryStream - Abion47
我看到每个流都有默认大小的内部缓冲区。您可以通过在结构中传递其值来更改默认缓冲区大小。我是在Visual Studio Express Edition 2013的调试模式下看到这个的。 - Neel Maheta
@NeelMaheta 对于最后一个评论的回答,流通常具有内部缓冲区,以保留从源中提取的中间数据,然后将该数据传递到目标。这不是用于有意存储的缓冲区,您不应将其视为自己的数据源。 - Abion47

4

缓冲区具有指定的大小/长度,用于存储数据。流(Stream)则用于从一个地方读取和写入信息到另一个地方。例如FileStream用于读写文件。

流本身具有缓冲区,当缓冲区填满其最大容量时,缓冲区将被刷新并读取或写入流中的数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接