【C语言】探索文件读写函数的全貌(二)https://developer.aliyun.com/article/1617244
七、文件的随机读写
由于文本文件和二进制文件使用方面存在差异,下面三个函数将采用二进制文件
7.1 fseek()
【函数部分说明】:
功能上:
- 重新定位流位置指示器,根据文件指针的位置和偏移量来定位文件指针
返回值:
- 成功,返回零,失败,返回非零值
【注意】:
- 二进制文件:要从原点偏移的字节数
- 文本文件:零或 ftell 返回的值
【原点】
特别注意的是起源(从哪个位置),用作偏移参考位置
- SEEK_SET :文件开头
- SEEK_CUR :文件指针的当前位置
- SEEK_END: 文件末尾
int main() { FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件 if (pf == NULL) { perror("fopen fail!!!"); return; } fputs("This is an apple", pf); fseek(pf, 3, SEEK_SET); fputs("sam", pf); fseek(pf, -3, SEEK_END);//文件指针往前走 fputs("xxx", pf); fclose return 0; }
7.2 ftell()
【函数部分说明】:
功能上:
- 返回流的位置指示器的当前值(返回文件指针相对于起始位置的偏移量 )
返回值:
- 对于二进制流,这是从文件开头开始的字节
- 对于文本流,数值可能没有意义
int main() { FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件 if (pf == NULL) { perror("fopen fail!!!"); return; } fputs("This is an apple", pf); fseek(pf, 0, SEEK_END); int size = ftell(pf); printf("%d", size);//size==16,源头到参考位置的字节数 fclose(pf); pf = NULL; return 0; }
7.3 rewind()
【函数部分说明】:
- 功能:让文件指针的位置回到文件的起始位置
int main() { FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件 if (pf == NULL) { perror("fopen fail!!!"); return; } fputs("This is an apple", pf); fseek(pf, 0, SEEK_END); rewind(pf); int size = ftell(pf); printf("%d", size); fclose(pf); pf = NULL; return 0; }
八、文件读取结束的判断
【牢记】:在文件读取过程中,不能用feof函数的返回值直接判断文件是否结束
8.1 ferror()
【函数部分说明】:
- 功能:检查错误指示器
- 返回值:检查是否设置了与流关联的错误指示器,如果设置了,则返回一个不同于零的值
8.2 feof()
【函数部分说明】:
- 功能:检查文件结束指示器
- 返回值:**如果设置了与流关联的文件结束指示符,则返回非零值。**否则,返回零。
小总结
文本文件读取是否结束:判断返回值是否为EOF(fgetc)或者NULL(fgets)
二进制文件读取是否结束:判断返回值是否小于实际要读的个数。
检查文件读取结束场景
while ((c = fgetc(fp)) != EOF) // 标准C I/O读取 { putchar(c); } //判断是什么原因结束的 if (ferror(fp)) puts("I/O error when reading"); else if (feof(fp)) puts("End of file reached successfully");
九、文件缓冲区
ANSIC
标准采⽤“缓冲文件系统”处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的⼤⼩根据C编译系统决定的.上述过程转换为下图展示。
【验证】:
int main() { FILE*pf = fopen("test.txt", "w"); fputs("abcdef", pf);//先将代码放在输出缓冲区 printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n"); Sleep(10000); printf("刷新缓冲区\n"); fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘) //注:fflush 在⾼版本的VS上不能使⽤了 printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n"); Sleep(10000); fclose(pf); //注:fclose在关闭⽂件的时候,也会刷新缓冲区 pf = NULL; return 0; }
【目的】:
程序延迟执行时间内,检查文本编辑器是否存在数据,等待程序睡眠时间过去,再次检查文本编辑器是否存在数据,验证内存和外存之间存在缓冲区
【结论】:
因为有缓冲区的存在,C语⾔在操作文件的时候,需要做刷新缓冲区或者在⽂件操作结束的时候关闭文件。如果不做,可能导致读写⽂件的问题