前言
在文件操作(二)中我们学习了顺序读写文件的函数,在这篇博客中我们将学习⽂件的随机读写,⽂件读取结束的判定。
fseek 函数允许您在文件中移动文件指针到指定位置。这是进行随机访问的基础,因为您可以使用 fseek 定位到文件中的任何位置,并从那里进行读取或写入。
int fseek(FILE *stream, long int offset, int whence)
参数:
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
offset -- 这是相对 whence 的偏移量,以字节为单位。
whence -- 参照点,可以是 SEEK_SET(从文件开始位置开始移动),
SEEK_CUR(从当前位置开始移动),
或 SEEK_END(从文件末尾开始移动)。
返回值:
如果成功,则该函数返回零,否则返回非零值。
#include
int main(){
FILE* pFile;
pFile = fopen("example.txt", "wb");//
fputs("This is an apple.", pFile);//将"This is an apple."写入文件
fseek(pFile, 9, SEEK_SET);//文件指针从文本开头,偏移量为9,最终指向‘n’
fputs(" sam", pFile);//将" sam"写入文件
fclose(pFile);
return 0;
}
ftell 函数用于获取当前文件指针的位置,以字节为单位。这可用于记录当前位置以便稍后进行恢复。
long int ftell(FILE *stream)
参数
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值
ftell 函数的返回值是当前文件指针的位置偏移量,以字节为单位,从文件的开头开始计算。
#include
int main() {
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
perror("无法打开文件");
return 1;
}
long position;
char buffer[256];
// 获取当前文件指针位置
position = ftell(file);
printf("当前文件指针位置:%ld\n", position);
// 读取文件的一部分数据
fgets(buffer, sizeof(buffer), file);
printf("读取的数据:%s\n", buffer);
// 获取新的文件指针位置
position = ftell(file);
printf("当前文件指针位置:%ld\n", position);
// 将文件指针重新定位到之前记录的位置
fseek(file, position, SEEK_SET);
// 再次读取相同的数据
fgets(buffer, sizeof(buffer), file);
printf("再次读取的数据:%s", buffer);
fclose(file);
return 0;
}
rewind 函数用于将文件指针重新定位到文件的开头,等效于使用 fseek(file, 0, SEEK_SET)。
void rewind(FILE *stream);
#include
int main() {
FILE* file = fopen("example.txt", "r");
if (file == NULL) {
perror("无法打开文件");
return 1;
}
char buffer[256];
// 读取文件的一部分数据
fgets(buffer, sizeof(buffer), file);
printf("读取的数据:%s\n", buffer);
// 将文件指针重新定位到文件的开头
rewind(file);
// 再次读取文件的一部分数据(与之前相同的数据)
fgets(buffer, sizeof(buffer), file);
printf("再次读取的数据:%s", buffer);
fclose(file);
return 0;
}
ferror 和 feof 是C标准库中用于处理文件流错误的两个函数,它们用于检测文件操作时可能发生的错误和文件流的结束。下面是它们的详细解释:
int ferror(FILE *stream);
如果在之前的文件操作中发生了错误,ferror 函数将返回非零值(通常是1),表示文件流出现了错误。
否则,它将返回零,表示没有错误发生。
int feof(FILE *stream);
如果文件流已经到达文件的结束位置,feof 函数将返回非零值(通常是1),表示已经到达文件末尾。
否则,它将返回零,表示文件流尚未到达文件末尾。
实例:
#include
#include
int main(void){
int c; // 注意:int,⾮char,要求处理EOF
FILE* fp = fopen("test.txt", "r");
if (!fp) {
perror("文件打开失败");
//EXIT_FAILURE 是一个标准的宏定义,通常表示程序以非正常状态退出。
return EXIT_FAILURE;
}
//fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOF
while ((c = fgetc(fp)) != EOF) {
putchar(c);
}
printf("\n");
//判断是什么原因结束的
if (ferror(fp))
puts("读取数据时发生了输入/输出错误");
else if (feof(fp))
puts("文件内容到达文件末尾");
fclose(fp);
}
文件缓冲区是在文件输入/输出操作期间用于临时存储数据的内存区域。它有助于提高文件操作的效率,减少了频繁的磁盘访问,因为磁盘访问通常比内存访问慢得多。
文件缓冲区的工作方式如下:
缓冲区的创建:在打开文件时,C标准库会为文件分配一个默认大小的缓冲区(通常是一块内存区域)。这个缓冲区称为文件缓冲区或流缓冲区。
缓冲模式:文件可以处于不同的缓冲模式下,主要有两种模式:
缓冲操作:当进行文件输入(如读取数据)时,数据首先被读入文件缓冲区。当进行文件输出(如写入数据)时,数据首先被写入文件缓冲区。
刷新缓冲区:缓冲区的数据可以在以下情况下被刷新(即写入磁盘或从磁盘读取):
关闭文件:当关闭文件时,文件缓冲区中的剩余数据通常会被刷新到磁盘。
示例:
#include
int main() {
FILE *file = fopen("example.txt", "w");
if (file == NULL) {
perror("无法打开文件");
return 1;
}
// 写入数据到文件缓冲区
fprintf(file, "这是一行文本\n");
// 关闭文件,缓冲区的数据会被刷新到磁盘
fclose(file);
return 0;
}
在上面的示例中,尽管我们在 fprintf 函数中写入了数据,但只有在 fclose 函数被调用时,数据才会被写入磁盘。这是因为关闭文件时会触发缓冲区的刷新操作。如果需要立即将数据写入磁盘,可以在 fprintf 后调用 fflush 函数。
结论:
因为有缓冲区的存在,C语⾔在操作⽂件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
如果你喜欢这篇文章,点赞+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。