将文本流式传输到文件时 "buffer size" 是什么意思

What does "buffer size" mean when streaming text to a file

我正在使用 .NET 中的 StreamWriter class 将大量文本输出到一个大文件中。

缓冲区大小是什么意思,它如何影响将文本写入文件时的速度和性能?

令人惊讶的是,我无法通过简单的 Google 搜索找到答案。

缓冲区大小是指在写入文件之前要保存在内存中的字符数。这个过程称为buffering。基本假设是写入文件比写入内存慢得多。

参见维基百科definition of data buffer

写入文件需要使用 WriteFile() winapi 函数。注意函数签名,第二个参数是 lpBuffer,一个包含需要写入的字节的缓冲区。第三个参数表示该缓冲区中有多少字节。

从技术上讲,您一次只能写入一个字节。但这是低效的,WriteFile() 不是一个非常便宜的函数。如果您改写一大块字节,效果会更好。将减少对 WriteFile 的调用。

所以StreamWriter有一个byte[]数组作为缓冲区。当您调用 Write/Line() 时,它将文本转换为字节并将它们复制到该缓冲区中。非常快。

在该数组已满之前一直有效。然后它 必须 调用 WriteFile() 再次清空缓冲区。这种情况发生的频率完全取决于缓冲区的大小和您写入的文本量。

StreamWriter 可以写入许多不同类型的流。它不一定只是磁盘上的一个文件。例如,您还可以使用它来将文本写入网络流。或者屏幕。或者通过管道到另一个进程。或者通过串行或 USB 端口连接到设备。或者通过 memory-mapped 文件进行记忆。等等,多种可能性。

当您进行 Write/Line() 调用时,很明显在幕后发生了非常不同的事情。如果您使用不同大小的缓冲区,您可能 使您的程序工作得更好。最重要的是,Microsoft 程序员无法预测您将如何使用 StreamWriter。因此可能不知道缓冲区大小是多少 "best"。他们不想把你逼到一个角落,在那里你总是不得不忍受他们选择的缓冲区大小。

所以您可以选择其他尺码。默认为 1024 字节。这是一个相当适中的大小,基于您将写入另一个也被缓冲的流的假设。与 FileStream 一样,您将在写入文件时使用它。它有一个 4096 字节的缓冲区。

如果您想知道哪个缓冲区大小最好,那么您必须进行试验。它无法预测,在引擎盖下运行的代码太多,无法让您猜测。但请注意,到目前为止,此类测试最常见的结果是它没有产生明显的效果。这是应该的方式,操作系统有责任在所有合理的情况下表现良好。当涉及到古怪 driver 时,您就有充分的理由尝试一下。