【文件随机读写和文件缓冲区】

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1.1fseek函数

1.1fseek函数

根据文件指针的位置和偏移量来定位文件指针。

int fseek ( FILE * stream, long int offset, int origin );

看不懂没关系举个例子你就明白了。

我们首先在text.txt文件中放入 “abcdef” 这些字符。
在这里插入图片描述

int main()
{
	FILE* pf = fopen("text.txt", "r");
	int ch = 0;
	if (pf == NULL)
	{
		perror("fopen");
	}
	else
	{
		ch = fgetc(pf);
		printf("%c\n", ch);//a
		ch = fgetc(pf);
		printf("%c\n", ch);//b
		ch = fgetc(pf);
		printf("%c\n", ch);//c
		
	}
	return 0;
}

然后我们用fgetc函数读取三个字符注意fgetc函数每读取完一个字符光标就会自动跳转到下一位此时已经读取完三个字符了光标自然就指向了d位置再读取的时候就会读取d。

但是我不想读取d位置了我想回头读取b位置。

此时有对fseek函数来说有三种方法
在这里插入图片描述
如果这样输入

fseek(pf, 1, SEEK_SET);

此时光标就移动到了最开始位置的下一个位置即b位置。
在这里插入图片描述
结果证实了上述结论。

我们还可以这样写

fseek(pf, -2, SEEK_CUR);

对标上面的图是从当前位置的光标向左移动2个光标位置当前位置的光标是在d处向左移动2个位置就移动到了b处此时读取就读取到了b。
在这里插入图片描述
至于最后一种方式SEEK_END 这样的读取方式较难以使用因为本来就不知道文件有多长有多少数据不过这种方式可以使用ftell函数来代替。

1.2 ftell函数

ong int ftell ( FILE * stream );

返回文件指针相对于起始位置的偏移量
ftell函数返回的是从当前位置相对于起始位置的偏移量。

仍以上面的例子为例

int main()
{
	FILE* pf = fopen("text.txt", "r");
	int ch = 0;
	if (pf == NULL)
	{
		perror("fopen");
	}
	else
	{
		ch = fgetc(pf);
		printf("%c\n", ch);//a
		ch = fgetc(pf);
		printf("%c\n", ch);//b
		ch = fgetc(pf);
		printf("%c\n", ch);//c
		int a = ftell(pf);
		printf("%d\n", a);
	}
	return 0;
}

此时光标移动到了c位置使用ftell函数返回相对起始位置的偏移量即 3

1.3 rewind函数

void rewind ( FILE * stream );

rewind 让文件指针的位置回到文件的起始位置

相比之下ftell函数和rewind函数更加简单粗暴。

int main()
{
	FILE* pf = fopen("text.txt", "r");
	int ch = 0;
	if (pf == NULL)
	{
		perror("fopen");
	}
	else
	{
		ch = fgetc(pf);
		printf("%c\n", ch);//a
		ch = fgetc(pf);
		printf("%c\n", ch);//b
		ch = fgetc(pf);
		printf("%c\n", ch);//c
		rewind(pf);
		ch = fgetc(pf);
		printf("%c\n", ch);//a
	}
	return 0;
}

举一个例子就可以理解了。

2. 被误解的feof函数

在文件读取过程中不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候判断是读取失败结束还是遇到文件尾结束。

  1. 文本文件读取是否结束判断返回值是否为 EOF fgetc 或者 NULL fgets
    例如
    fgetc 判断是否为 EOF .
    fgets 判断返回值是否为 NULL .

  2. 二进制文件的读取结束判断判断返回值是否小于实际要读的个数。
    例如
    fread判断返回值是否小于实际要读的个数。

举个简单例子

int main(void)
{
	int c; // 注意int非char要求处理EOF
	FILE* fp = fopen("test.txt", "r");
	if (!fp) {
		perror("File opening failed");
		return EXIT_FAILURE;
	}
	//fgetc 当读取失败的时候或者遇到文件结束的时候都会返回EOF
	while ((c = fgetc(fp)) != EOF) 
	{
		putchar(c);
	}
	//判断是什么原因结束的
	if (ferror(fp))
		puts("I/O error when reading");
	else if (feof(fp))
		puts("End of file reached successfully");
	fclose(fp);
}

当读取结束时无论是读取失败还是遇到文件末尾 都会返回EOF此时就有两种情况分别用ferror和feof函数进行判断即可。

2.1 文件缓冲区

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

在这里插入图片描述
意思是这样的
当我们写程序向文件中写入信息时这些信息会先被放在输出缓冲区中当输出缓冲区被充满后再依次送到硬盘中。
当我们写程序向文件中读取信息时这些信息会先被放在输入缓冲区中当输入缓冲区被充满后再依次送到我们手中。

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6