fread,fwrite数据写磁盘流程|fflush--linux编程写文件注意问题(fwrite没有直接写入文件)
目录
fwrite,fflush-----linux编程写文件注意问题(fwrite没有直接写入文件)
fread,fwrite数据写入磁盘的流程
2019-11-07 09:28:08
fwrite,fflush
fwrite,fflush,你不知道的事!_zhangxiong2532的博客-CSDN博客_fwrite和fflush
fread,fwrite>> CLib buffer内存缓冲(用户空间) -->fflush>>page cache内核缓冲--->fsync>>磁盘
fflush:标准I/O函数(如:fread,fwrite)会在内存建立缓冲,该函数刷新内存缓冲,将内容写入内核缓冲,要想将其写入磁盘,还需要调用fsync。(先调用fflush后调用fsync,否则不起作用)。
sync、fsync、fdatasync、fflush函数区别和使用举例_lhb0709的博客-CSDN博客_fsync
调用fwrite后,把数据从application buffer 拷贝到了 CLib buffer,即C库标准IObuffer。fwrite返回后,数据还在CLib buffer,如果这时候进程core掉。这些数据会丢失。没有写到磁盘介质上。当调用fclose的时候,fclose调用会把这些数据刷到高速缓冲块,如果不手动调用fsync,fclose之后掉电再查看数据可能没有刷到磁盘上。
除了fclose方法外,还有一个主动刷新操作fflush 函数,不过fflush函数只是把数据从CLib buffer 拷贝到page cache 中,并没有刷新到磁盘上,从page cache刷新到磁盘上可以通过调用fsync函数完成。
从上面类子看到,一个常用的fwrite函数过程,基本上历经千辛万苦,数据经过多次copy,才到达目的地。有人心生疑问,这样会提高性能吗,反而会降低性能吧。这个问题先放一放。
有人说,我不想通过fwrite+fflush这样组合,我想直接写到page cache。这就是我们常见的文件IO调用read/write函数。这些函数基本上是一个函数对应着一个系统调用,如sys_read/sys_write. 调用write函数,是直接通过系统调用把数据从应用层拷贝到内核层,从application buffer 拷贝到 page cache 中。
关于linux系统调用write()
调用一次write()完毕,是不是已经写到磁盘上了?
是不是调用一次write(),就是一次写请求,不管写多少个字符进去,调用完都已经通过缓冲区写到磁盘上了?
那么fsync()这个函数是不是指将缓冲区的写到磁盘上,如果是,write完再fsync是不是多此一举?
我想实现的是可以先创建一个文件,然后写一些东西到该文件的缓冲区,再调用fsync()写入磁盘,请问如何实现?
当你用write之后,内核就响应write系统调用sys_write,然后向高速磁盘缓冲块page cache写入数据,之后,你如果用stat,或者read时,系统首先会在高速缓冲块中去查看相应的数据是否在块中,如果不是,然后再调用磁盘驱动加载磁盘数据到高速缓冲块中,然后再由高速缓冲块中返回你要的数据!!!!!这就是你用stat()输出st_size,就是写入的个数的原因!!!!!
系统会在合适的时机再向真正的硬件写入高速缓冲块中的数据,也可以用fsync强制把高速缓冲块中的相应数据写入磁盘!!!!!!!
关于write()和fsync()__write_fsync_高速缓_缓冲区_关于__
https://blog.csdn.net/xiaofei0859/article/details/51145051
fwrite和write的区别
fwrite是ANSI C的写函数,带缓冲(应用层缓冲);write/read是POSIX 的写函数,不带缓冲(应用层缓冲)
请问:
1. 带不带缓冲是指什么意思??
fwrite-->clib buffer-->pagecache-->……
write-->pagecache-->……
2. 既然write不带缓冲,为什么write(int fd, const void *buf, size_t count) 是把缓冲区的字节写入fd相关联的文件中,read(int fd, void *buf, size_t count),是将fd关联的文件读入到缓冲区buf中??
首先要明白不带缓冲的概念:
所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用。系统内核对磁盘的读写都会提供一个块缓冲,当用write函数对其写数据时,直接调用系统调用,将数据写入到块缓冲进行排队,当块缓冲达到一定的量时,才会把数据写入磁盘。因此所谓的不带缓冲的I/O是指进程不提供缓冲功能。
每调用一次write或read函数,直接系统调用。
而带缓冲的I/O是指进程对输入输出流进行了改进,提供了一个流缓冲,当用fwrite函数网磁盘写数据时,先把数据写入流缓冲区中,当达到一定条件,比如流缓冲区满了,或刷新流缓冲,这时候才会把数据一次送往内核提供的块缓冲,再经块缓冲写入磁盘
fwrite是带缓冲的,write不带缓冲。
举例说明如下:
如果文件的大小是8k。
若用write,且只分配了2k的缓存,则要将此文件读入需要做4次系统调用。(内核空间和用户空间切换4次)
若用fwrite,则系统自动分配缓存,则读入此文件只要一次系统调用。
也就是用write要读4次磁盘,而用fwrite则只要读1次磁盘。所以fwrite的效率比write要高4倍。
另外,如果程序对内存有限制,则用write比较好。
系统调用write的效率取决于用户buff的大小和要写入的总数量,如果buff太小,进入内核空间的次数会增加,效率就低下。而fwrite会自动完成缓存分配任务,减少了实际出现的系统调用,所以效率比较高。
1. 所谓缓冲区,就是一段内存。里面存有内容。fwrite有缓冲,代表当fwrite调用结束之后,它所要求写入文件的内容,可能还有一部分在内存当中,如果要确保写入,需要调用fflush。
fwrite,fflush-----linux编程写文件注意问题(fwrite没有直接写入文件)
2018-10-22 10:13:26
最近项目代码中遇到很多奇怪的问题,比如,在某个程序中用fwrite向配置文件中写入一些数据,而在另一段代码中需要读取该配置文件中的数据,写文件那段程序已经执行完了,但是数据并没有被写入文件,进而导致读文件的代码读不到数据,程序很难按理想的方式运行。这样下来将会导致一些列的问题,我今天就被这个问题纠结了一下午...那么这个问题是什么原因导致的呢,该怎么解决呢?
导致问题的原因是 用fwrite函数写数据的时候,fwrite先将数据写到内存中的缓冲区内,
等程序结束后才会将数据由缓冲区写入文件。所以我遇到的问题原因是整个函数还没有运行完毕,写入的数据还在缓冲区内。
解决办法就只有靠fflush()函数了。
#include<stdio.h>
int fflush(FILE *stream)
该函数的作用就是刷新缓冲区
做法是,在写入的数据在函数结束之前就需要的时候,调用fwrite等函数后,紧接着调用fflush()函数将缓冲区刷新,这样数据就会被立刻写入文件而不用等到程序结束(因为之前的数据都在缓冲区里)。
下面通过一个简单的例子让小伙伴们 加深理解:
int main()
{
FILE *fp = fopen("./file.txt", "a");
if(fp == NULL)
{
printf("open file err!\n");
return -1;
}
fwrite("hello", 5, 1, fp);
//fflush(fp);
close(fp);
while(1)
{
sleep(5);
}
return 0;
}
如上程序,当程序一直不退出的时候,虽然已经调用了fwrite但是数据却在缓冲区里,而并不在文件中,这时你可以查看改路径下的file.txt文件,你会发现文件已经建立但是大小为0,如果你在fwrite之后用fflush函数后数据就会立刻写入文件,我总结就这么多,不喜勿喷,希望对小伙伴们有帮助。
-----新增2020.12.08
详细内容:【linux】随机读写之DirectIO|MMAP和DIRECT IO区别_bandaoyu的note-CSDN博客_c++ direct io
fwrite返回后,数据还在CLib buffer,如果这时候进程core掉。这些数据会丢失。没有写到磁盘介质上。当调用fclose的时候,fclose调用会把这些数据刷新到磁盘介质上。除了fclose方法外,还有一个主动刷新操作fflush 函数,不过fflush函数只是把数据从CLib buffer 拷贝到page cache 中,并没有刷新到磁盘上,从page cache刷新到磁盘上可以通过调用fsync函数完成。
从上面类子看到,一个常用的fwrite函数过程,基本上历经千辛万苦,数据经过多次copy,才到达目的地。有人心生疑问,这样会提高性能吗,反而会降低性能吧。这个问题先放一放。
over!
---------------------
作者:zhangxiong2532
来源:CSDN
原文:https://blog.csdn.net/zhangxiong2532/article/details/50608898
版权声明:本文为博主原创文章,转载请附上博文链接!