文件操作(3)

本文介绍了C语言中文件的随机读写,包括fseek和ftell函数的使用,解释了如何判断文件结束,并探讨了文件缓冲区的概念和作用。同时,讲解了文本文件和二进制文件的区别,以及如何在实际操作中判断文件结束。最后,通过示例代码展示了文件缓冲区的影响,强调了缓冲区提高效率的重要性。
摘要由CSDN通过智能技术生成

一、文件的随机读写

1.fseek

它的作用是将文件指针移动到指定偏移量的位置,第一个参数是文件指针,第二个参数是long类型的偏移量,第三个参数是可选参数,代表现在文件指针的最初位置。若文件指针最初是起始位置,那就输入SEEK_CUR,文件末尾就输入SEEK_END,其余情况输入SEEK_SET。

我们下面尝试用这个函数往文件中的字符串放进一个字符

#include<stdio.h>
int main()
{
	FILE* pf = fopen("hello world.txt", "w");
	fputs("hello world", pf);//往文件输入hello world
	fseek(pf, -3, SEEK_END);//当前文件指针已经在末尾了,把它放到3偏移量处
	fputc('c', pf);//在当前位置放入字符c
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果 

 有人可能会说,有时文件指针的移动到的位置无法判断,怎么知道它相对于原始位置的偏移量呢?这就需要下一个函数。

2.ftell

返回文件指针当前位置相对于文件起始位置的偏移量,返回类型为long

 我们不妨对上个函数测试的代码,再加入ftell,看看当前位置的偏移量是多少。

#include<stdio.h>
int main()
{
	FILE* pf = fopen("hello world.txt", "w");
	fputs("hello world", pf);//往文件输入hello world
	fseek(pf, -3, SEEK_END);//当前文件指针已经在末尾了,把它放到3偏移量处
	fputc('c', pf);//在当前位置放入字符c
    long t = ftell(pf);//用t变量接收偏移量
	printf("%d",t);//打印偏移量
    fclose(pf);
	pf = NULL;
	return 0;
}

当前文件指针应该处于r位置,所以相对于起始的偏移量是9,说明我们打印的结果是正确的。

有些情况我们需要将指针回溯到起始位置,当然你可以用ftell算出当前偏移量,再调用fseek函数将指针回到原有位置。这比较繁琐,这里提供一个函数——REWIND,可以直接将指针回到起始位置。 

3.rewind

不需要任何参数,只要把文件指针传入即可。 

二、文本文件和二进制文件

二进制文件:

包含在 ASCII及扩展 ASCII 字符中编写的数据或程序指令的文件。计算机文件基本上分为二种:二进制文件和 ASCII(也称纯文本文件),图形文件及文字处理程序等计算机程序都属于二进制文件。这些文件含有特殊的格式及计算机代码。ASCII 则是可以用任何文字处理程序阅读的简单文本文件。

在计算机底层中,是以二进制的方式储存文件,如果对数据不加以处理,直接放入文件中,这个文件就叫做二进制文件,打开二进制文件将会是看不懂的一堆乱码。 

如果要求在外存上以 ASCII 码的形式存储,则需要在存储前转换。以 ASCII 字符的形式存储的文件就是 本文件

三、文件结束的判断

1.错误使用的feof

feof并不是判断文件是否结束,而是已知文件结束,用于判断文件结束的原因——是正常文件结束,还是文件读取错误。

 下面给出判断文件结束的几种方法:

1.文本文件使用fgetc,看是否返回EOF
2.文本文件使用fgets,看是否返回NULL
3.二进制文件使用fread,看是否正确返回读取的个数

四、文件缓冲区

ANSIC 标准采用缓冲文件系统处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序
每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装
满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓
冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根 据C编译系统决定的。

实际上,在我们程序从文件中读取数据的过程中,还有一个中介——文件缓冲区,系统会将我们要读取的数据放在文件缓冲区中,如果文件缓冲区满了,就开始读取数据。

我们用下面一段代码在编译器测试缓冲区的效果,

#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
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;
 }

如果真的存在文件缓冲区的话,在第一次用fputs输入abcdef到文件中后,让他睡眠10秒,打开文件并不会出现数据,因为数据还在缓冲区当中,只有我们刷新缓冲区后,系统才会让数据读取到文件中。

 

 上面测试的结果说明确实存在文件缓冲区,每次程序读取数据时,只有缓冲区满了,或者我们手动刷新缓冲区,才会读取数据。

但是为什么要有缓冲区呢?

 原因是如果我们没有缓冲区,每读取一次数据就要向系统申请一次,会频繁打扰到系统的工作,举个生活中的例子:习题课上,一个同学每有一个问题就向老师提问,这样不但老师效率低了,还影响到其他同学提问,所以老师提议让所有同学攒够三个问题再来提问,这样老师一次性解决,就提高了效率。所以缓冲区是有必要的。

本章完。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值