0

fprintf当使用或写入文件时,我找不到任何关于缓冲是否已经隐式完成的信息fwrite。我知道这可能是实现/平台相关的功能。我感兴趣的是,我是否至少可以期望它在现代流行平台(如 Windows、Linux 或 Mac OS X)上有效实现?

AFAIK,通常 I/O 例程的缓冲在 2 个级别上完成:

  1. 库级别:可以是 C 标准库,也可以是 Java SDK ( BufferedOutputStream) 等;
  2. 操作系统级别:现代平台广泛缓存/缓冲 I/O 操作。

我的问题是关于#1,而不是#2(我知道这已经是真的了)。换句话说,我可以期望所有现代平台的 C 标准库实现都能利用缓冲吗?

如果不是,那么手动创建一个缓冲区(巧妙地选择大小)并在溢出时刷新它是解决问题的好方法吗?

结论


感谢所有指出 和 之类的功能的setbufsetvbuf。这些是我正在寻找回答我的问题的确切证据。有用的提取物:

如果已知所有文件不引用交互式设备,则所有文件都使用默认分配的缓冲区(完全缓冲)打开。此函数可用于设置特定内存块用作缓冲区或禁用流的缓冲。

默认情况下,默认流stdinstdout完全缓冲,如果已知它们不引用交互式设备。否则,它们可能默认为行缓冲或非缓冲,具体取决于系统和库实现。也是如此stderr,默认情况下总是行缓冲或无缓冲。

4

4 回答 4

3

在大多数情况下,stdio 例程的缓冲被调整为与相关操作系统的典型块大小一致。这样做是为了在默认情况下优化 I/O 操作的数量。当然,你总是可以用setbuf()/setvbuf()例程来改变它。

除非您正在做一些特别的事情,否则您应该坚持使用默认缓冲,因为您可以确定它在您的操作系统上大部分是最佳的(对于典型场景)。

唯一可以证明这一点的情况是,当您想使用 stdio 库与不适合它的 I/O 通道进行交互时,您可能希望完全禁用缓冲。但我不会经常看到这种情况。

于 2013-10-31T21:21:07.470 回答
1

正如@David 所说,您可以期待合理的缓冲(在两个级别上)。

但是, 和 之间可能存在巨大差异fprintffwrite因为fprintf它解释了格式字符串。如果你对它进行堆栈采样,你会发现有很大一部分时间将双精度数转换为字符串,诸如此类。

于 2013-10-31T21:12:42.510 回答
1

您可以放心地假设标准 I/O 在任何现代系统上都得到了合理的缓冲。

于 2013-10-31T21:09:03.533 回答
1

C IO 库允许使用setvbuf. 如果您未指定任何内容,则标准要求“打开时,当且仅当可以确定不引用交互式设备时,才完全缓冲流。”,该要求也适用于并且stdin即使不缓冲如果可以检测到它被定向到非交互式设备。stdoutstderr

于 2013-10-31T21:29:37.160 回答