https://m.toutiaocdn.com/i6866459131956429324/?app=news_article×tamp=1598779013&use_new_style=1&req_id=202008301716530101300361592955F36C&group_id=6866459131956429324
大家好,今天和大家聊一聊C语言的文件操作。
C语言中,标准库函数提供的文件操作API的声明,存放在stdio.h文件中。它是C语言标准库的一部分,在支持C语言的平台上都可以使用,也就不需要担心可移植性的问题了。
在C语言标准库中,I/O操作的对象是一个叫做“流(stream)”的抽象概念。你可以把它想象成双排水管,一个进水,另外一个出水,而水就是我们操作的数据。
既然是水管,它的里面就会有一些还没流干净的水,这些没流干净的水就是系统缓存的一些数据。这些缓存的目的是节省CPU的资源并提高系统的性能。系统会把几次写入的数据攒在一起,数据的大小达到了预先设定的上限,系统就会一次性把它们写入到硬件中去。读取数据时,系统读取的数据范围会比用户要求的更大一些,这样,用户下一次要读取的数据如果在上一次的缓存中,系统就不需要再去访问硬件了。
// FILE *fopen(const char *filename, const char *mode);//// fopen 函数按照指定的文件路径和模式打开文件,会在内部创建一个文件对象,并返回这个对象的指针// filename : 可以是文件的绝对路径,也可以是相对路径// mode : 这个参数比较灵活, // |-----------------------------------------------------------------------------------------------------|// |'r' | 以只可以读取的模式打开一个文件,文件必须已存在。 |// |-------|----------------------------------------------------------------------------------------------|// |'w' | 创建一个空白文件,用来写入。如果文件已经存在,内容会被清除掉。|// |-------|----------------------------------------------------------------------------------------------|// |'a' | 打开一个文件并在文件的最后追加内容。 |// | | 重定位操作(fseek, fsetpos, rewind)在这种模式下无效。 |// | | 如果不存在指定的文件,系统会新建这个文件。 |// |-------|----------------------------------------------------------------------------------------------|// |'r+' | 以可读写的模式打开一个文件,文件必须已经存在。 |// |-------|----------------------------------------------------------------------------------------------|// |'w+' | 以可读写的模式创建一个空白文件,文件如果存在,内容会被清除掉。|// |-------|----------------------------------------------------------------------------------------------|// |'a+' | 以追加并可读的模式打开一个文件。 |// | | 重定位操作(fseek, fsetpos, rewind)会影响下一次的读操作。 |// | | 但是,写操作会把定位器移动到文件末尾。 |// | | 如果不存在指定的文件,系统会新建这个文件。 |// |--------------------------------------------------------------------------------------------------- --|// 上面的说明是针对文本文件的,如果是读写二进制文件,只要再加个'b'就行了,例如:'ab+'// 错误时返回值为NULL#include <stdio.h>int main (){ FILE * pFile; pFile = fopen ('myfile.txt','w'); if (pFile!=NULL) { fputs ('fopen example',pFile); fclose (pFile); } return 0;}// FILE * freopen ( const char * filename, const char * mode, FILE * stream );// 这个API有两种行为:// 1. 如果filename为空,它就改变stream的mode。// 2. 如果filename不为空,那么就打开这个文件,并和stream结合起来。// 如果函数执行成功,就返回stream参数。#include <stdio.h>int main (){ freopen ('myfile.txt','w',stdout); printf ('This sentence is redirected to a file.'); fclose (stdout); return 0;}
// FILE * freopen ( const char * filename, const char * mode, FILE * stream );// 这个API有两种行为:// 1. 如果filename为空,它就改变stream的mode。// 2. 如果filename不为空,那么就打开这个文件,并和stream结合起来。// 如果函数执行成功,就返回stream参数。#include <stdio.h>int main (){ freopen ('myfile.txt','w',stdout); printf ('This sentence is redirected to a file.'); fclose (stdout); return 0;}
// void setbuf ( FILE * stream, char * buffer );// 这个API用来设置文件流的缓存,调用时机是打开文件后,读写操作前。// 系统默认缓存的大小至少是BUFSIZ, 这个宏由系统定义。// 如果buffer是NULL,则代表不对这个流使用缓存,所有的读写都立刻反映到硬件上。/* setbuf example */#include <stdio.h>int main (){ char buffer[BUFSIZ]; FILE *pFile1, *pFile2; pFile1=fopen ('myfile1.txt','w'); pFile2=fopen ('myfile2.txt','a'); setbuf ( pFile1 , buffer ); fputs ('This is sent to a buffered stream',pFile1); fflush (pFile1); setbuf ( pFile2 , NULL ); fputs ('This is sent to an unbuffered stream',pFile2); fclose (pFile1); fclose (pFile2); return 0;}
// int setvbuf ( FILE * stream, char * buffer, int mode, size_t size );// 这个API可以为stream设置缓存并设置缓存的大小和模式。// 调用时机和setbuf一样。// 如果buffer为NULL,系统会分配一块大小为size的缓存。// 关于mode,可以是以下取值:// -------------------------------------------------------------------------------------------------------------// | _IOFBF |完整缓存,默认模式 |// |------------------------------------------------------------------------------------------------------------// | _IOLBF| 行缓存,输出时,每当遇到换行符,系统将缓存写入硬件并清空缓存。|// | | 输入时,系统每次读入一行数据。 |// |-------------------------------------------------------------------------------------------------------------// | _IONBF| 无缓存模式 |// |-------------------------------------------------------------------------------------------------------------#include <stdio.h>int main (){ FILE *pFile; pFile=fopen ('myfile.txt','w'); setvbuf ( pFile , NULL , _IOFBF , 1024 ); // File operations here fclose (pFile); return 0;}
// int fflush ( FILE * stream );// 当我们想要把缓存中的数据立刻写入硬件中时,可以调用这个API。// 调用fclose和freopen也有同样的效果#include <stdio.h>char mybuffer[80];int main(){ FILE * pFile; pFile = fopen ('example.txt','r+'); if (pFile == NULL) perror ('Error opening file'); else { fputs ('test',pFile); fflush (pFile); // flushing or repositioning required fgets (mybuffer,80,pFile); puts (mybuffer); fclose (pFile); return 0; }}
// int fclose ( FILE * stream );// 当我们完成了所有的读写操作,别忘了调用这个API把文件流关闭。#include <stdio.h>int main (){ FILE * pFile; pFile = fopen ('myfile.txt','wt'); fprintf (pFile, 'fclose example'); fclose (pFile); return 0;}
本次的内容就到这里了,希望对大家有所帮助。如果觉得感兴趣的话,可以点赞加关注。
联系客服