在C++中,有一个std::fwrite()
将缓冲区写入磁盘上的文件。fwrite是否缓冲输出?
你可以告诉我,如果有fwrite执行内的任何缓冲区?
即,如果我多次调用fwrite()(比如说10次),它是否真的会在不同的时间调用文件I/O?
我在问这个Ubuntu 10.04环境。
在C++中,有一个std::fwrite()
将缓冲区写入磁盘上的文件。fwrite是否缓冲输出?
你可以告诉我,如果有fwrite执行内的任何缓冲区?
即,如果我多次调用fwrite()(比如说10次),它是否真的会在不同的时间调用文件I/O?
我在问这个Ubuntu 10.04环境。
是的,它被缓冲。缓冲区的大小由BUFSIZ
定义。 (Thanks @ladenedge。)十个足够大的操作将导致十个系统调用。
您也可以使用std::setbuf
和std::setvbuf
设置您自己的缓冲区。
cstdio
中的函数从C继承.C++中的首选接口是fstream
和filebuf
。
这取决于。在大多数平台上,文件IO被缓存,因此存在fflush()
调用以将缓存数据写入磁盘 - 在这方面,第一个问题的答案是(通常)是“是”,第二个是“否”。也就是说,对于任何特定的平台,无论如何不能保证这种想象 - 通常,标准只是指定了这些功能的接口,而不是它们的实现。另外,如果缓存变为“满”,调用fwrite()
的相当可能会导致隐式刷新,在这种情况下调用fwrite()
实际上可能会触发文件IO - 尤其是在调用fwrite()
具有大量数据时。
库IO功能缓冲,但也是系统IO功能通常是;不仅如此,磁盘控制器也具有缓存。实际上,通常磁盘问题并不能确保您的输出缓存,但确保在您需要时将其真正写入磁盘。:) – 2010-05-10 20:43:44
@Matteo,我知道你的意思 - 例如,如果在缓存写入磁盘之前程序崩溃,使用fwrite编写错误日志可能会很有意思。幸运的是,对于那个... fflush – Mac 2010-05-10 20:47:50
“标准只规定了这些功能的接口,而不是它们的实现”并不准确。虽然标准没有指定实现,但它确实指定了行为。在这种情况下,标准确定FILE *被缓冲(C++在17.3.1.4/1中包含C标准,而C标准定义FILE *在7.19.5.6/2中被缓冲)。 – 2010-05-10 21:00:57
这取决于库的实现。你可以看看如dtruss或strace来查看实现实际调用了哪些系统调用。
你为什么在意这件事?
我不相信标准对此有任何说明,但一般来说:操作系统不会决定做多少I/O操作。它可能是1它可能是10.它甚至可能更多,如果数据量很大。大多数操作系统允许你控制I/O的行为方式,但是AFAIK没有可移植的方式来执行它。 (并且通常你不想要)
FILE*
I/O可以被缓冲,但它不一定是(它可以是不同的每个流)。此外,有多种方法可以进行缓冲(完全缓冲,其中缓冲区未被刷新,直到其已满或者对fflush
进行明确调用或缓冲区未被刷新直到看到EOL时进行行缓冲)。也可以完全关闭缓冲。
您可以使用setvbuf调用更改缓冲类型。
我相信默认的缓冲区大小是'BUFSIZ',就像stdio.h中定义的一样,当然呼叫者不应该需要这些信息。 'setbuf'可以用来控制某些系统的大小。 – ladenedge 2010-05-10 20:22:04
大声笑,你发布的字面确切的第二次我做了一个编辑:“lasecge 1秒前” – Potatoswatter 2010-05-10 20:22:41