以下是使用fflush()的示例代码:
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>
void flush(FILE *stream);
int main(void)
{
FILE *stream;
char msg[] = "This is a test";
/* create a file */
stream = fopen("DUMMY.FIL", "w");
/* write some data to the file */
fwrite(msg, strlen(msg), 1, stream);
clrscr();
printf("Press any key to flush DUMMY.FIL:");
getch();
/* flush the data to DUMMY.FIL without closing it */
flush(stream);
printf("\nFile was flushed, Press any key to quit:");
getch();
return 0;
}
void flush(FILE *stream)
{
int duphandle;
/* flush the stream's internal buffer */
fflush(stream);
/* make a duplicate file handle */
duphandle = dup(fileno(stream));
/* close the duplicate handle to flush the DOS buffer */
close(duphandle);
}
Run Code Online (Sandbox Code Playgroud)
我所知道的关于fflush()的是它是一个用于刷新输出缓冲区的库函数.我想知道使用fflush()的基本目的是什么,我在哪里可以使用它.主要是我有兴趣知道使用fflush()会有什么问题.
tor*_*rek 45
有点难以说出"可能出现问题"(过度?)的用法fflush.根据您的目标和方法,各种事物都可能成为或成为问题.可能更好的方式来看待这个是什么意图fflush.
首先要考虑的是fflush仅在输出流上定义.输出流将"要写入文件的内容"收集到一个大(ish)缓冲区中,然后将该缓冲区写入该文件.这种收集和写入的要点是以两种方式提高速度/效率:
因此,提供C库及其stdio流实现的人会在您的操作系统上执行任何适当的操作,以找到"合理优化"的块大小,并将所有输出收集到该大小的块中.(今天的数字4096,8192,16384和65536往往是好的,但它实际上取决于操作系统,有时也取决于底层文件系统.注意"更大"并不总是"更好":例如,一次以4千兆字节为单位的数据流传输数据可能比以64千字节的数据块执行更差.)
但这会产生问题.假设您正在写入一个文件,例如带有日期和时间戳记和消息的日志文件,并且您的代码将在以后继续写入该文件,但是现在,它希望暂停一段时间并让它日志分析器读取日志文件的当前内容.一种选择是使用fclose关闭日志文件,然后fopen再次打开它以便稍后添加更多数据.但是,将任何挂起的日志消息推送到底层操作系统文件,但保持文件打开会更有效.这是什么fflush.
缓冲也会产生另一个问题.假设您的代码有一些错误,它有时会崩溃,但您不确定它是否会崩溃.假设你已经写了一些东西,这些数据传递到底层文件系统是非常重要的.fflush在调用可能崩溃的潜在错误代码之前,您可以调用将数据推送到操作系统.(有时这对调试很有用.)
或者,假设您使用的是类Unix系统,并进行fork系统调用.此调用会复制整个用户空间(复制原始进程).stdio缓冲区位于用户空间中,因此克隆在fork调用时具有与原始进程相同的缓存但尚未写入的数据.同样,解决问题的一种方法是fflush在执行之前使用将缓冲的数据推出fork.如果一切都在之前fork,那就没有什么可复制的; 新鲜克隆不会尝试写入缓冲数据,因为它不再存在.
更fflush-es您添加,更多的你击败收藏起来,大量数据的最初的想法.也就是说,你正在做出权衡:大块更有效率,但是会引起一些其他问题,所以你做出决定:"在这里效率低下,解决比单纯效率更重要的问题".你打电话fflush.
有时问题只是"调试软件".在这种情况下,fflush您可以使用setbuf和等函数setvbuf来改变stdio流的缓冲行为,而不是重复调用.与添加大量fflush调用相比,这更方便(更少甚至不需要代码更改 - 您可以使用标志控制set-buffering调用),因此可以将其视为"使用中的问题(或过度使用)的fflush".