本文共 3351 字,大约阅读时间需要 11 分钟。
文件是计算机世界中非常重要的一种资源,它 Pepople 通常与存储磁盘相关联。程序设计时,文件被分为程序文件和数据文件两种类型,这两类文件在功能上有本质的区别。本文将深入探讨文件操作的核心知识,包括文件类型、文件名、文件缓冲区、文件指针等概念,并涵盖常用文件操作函数的使用方法。
程序文件是存储程序代码的文件,主要包括源程序文件(如.c
文件)、目标程序文件(如Windows环境下的.obj
文件)和可执行程序(如Windows环境下的.exe
文件)。这些文件包含程序的源代码或编译生成的中间或最终产物。
相比之下,数据文件不包含程序代码,而是程序运行时读写的数据。根据数据的组织形式,数据文件又可以划分为文本文件和二进制文件。文本文件是将数据以ASCII码的形式存储在磁盘上的文件,而二进制文件是直接以二进制数据形式存储的文件。
数据在内存中以二进制形式存储。如果直接以二进制格式输出到外存,则称为二进制文件。如果需要以ASCII字符形式存储,则在存储前需要进行转换,这样的文件就被称为文本文件。
例如,整数10000如果以ASCII码形式输出到磁盘,每个字符占用一个字节,共占用5个字节。但如果以二进制形式输出,则仅占用4个字节。
在进行文件操作之前,程序需要先打开文件,使用完毕后需要关闭文件。文件的打开与关闭操作可以通过调用fopen
和fclose
函数来实现。
fopen
函数的原型为:
FILE* fopen(char const* _FileName, char const* _Mode);
_FileName
:指向字符数组的指针,指定要打开的文件名。_Mode
:指定打开文件的模式,常见模式包括"r"
(只读)、"w"
(读写)。 "rb"
),则打开操作会失败。fclose
函数的原型为:
int fclose(FILE* stream);
参数stream
指向要关闭的文件指针。关闭文件后,指针应重置为NULL
以避免操作失败。
操作文件时,最常会遇到的问题是文件不存在。检查错误时可以使用strerror
函数获取错误信息:
if (fp == NULL) { printf("文件打开失败:%s\n", strerror(errno));}
文件操作中,读写文件的具体方法通过fgetc
/fputc
、fgets
/fputs
等函数实现。这些函数不仅适用于本地文件,也适用于标准输入输出流(如stdin
和stdout
)。
fgetc
/fputc
函数用于单个字符的读写:
int fgetc(FILE* stream);int fputc(int character, FILE* stream);
fgetc
从文件中读取一个字符,并返回其ASCII值。如果返回EOF
则表示读取结束。fputc
将给定字符写入文件中。**fgets
/fputs
**函数用于字符串的读写:
char* fgets(char* str, int num, FILE* stream);int fputs(const char* str, FILE* stream);
fgets
从文件中读取至多num
个字符,返回NULL
表示末尾。fputs
将字符串写入文件中,操作结束后应确保缓冲区已 flush。如果需要批量读写多个记录,则可以使用fscanf
/fprintf
函数进行格式化读写:
int fscanf(FILE* stream, const char* format, ...);int fprintf(FILE* stream, const char* format, ...);
这两个函数的唯一区别是第二个参数是文件指针,fscanf
用于从文件读取格式化数据,fprintf
用于将格式化数据写入文件。
对于二进制文件,可以使用fread
和fwrite
函数进行读写:
size_t fread(void* ptr, size_t size, size_t count, FILE* stream);size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream);
fread
从文件中读取count
个大小为size
的数据块到ptr
中,返回实际读取的数据个数。fwrite
将ptr
指针指向的数据按size
和count
规则写入文件中。对于需要在文件中定位特定位置的操作,可以使用fseek
和ftell
函数:
int fseek(FILE* stream, long int offset, int origin);long int ftell(FILE* stream);
fseek
将文件指针从origin
位置移动到offset
偏移处,参数的origin
可选SEEK_SET
(起始位置)、SEEK_CUR
(当前位置)或SEEK_END
(末尾)。ftell
返回文件指针相对于文件起始位置的偏移量。可以结合fseek
和ftell
实现文件的定位功能。例如,从文件开头查找特定记录的位置:
// 假设文件中有记录结构体`struct Record`size_t record_len = sizeof(struct Record);FILE* fp = fopen("data.db", "r");if (fp == NULL) { perror("无法打开文件");}long int current_pos = ftell(fp);// 定位文件末尾fseek(fp, 0, SEEK_END);long int file_size = ftell(fp);// 移动指针到特定位置fseek(fp, current_pos + record_len, SEEK_SET);// 读取要查找的记录struct Record requested_record = { 0 };int read_bytes = fread(&requested_record, sizeof(struct Record), 1, fp);if (read_bytes != 1) { // 协商错误信息 if (ferror(fp)) { perror("读取记录失败"); } else { printf("已到达文件末尾\n"); }}fclose(fp);
在某些情况下,程序需要随机访问文件并对文件内容进行修改或查看当前位置的信息,可以使用fseek
函数将文件指针定位到特定位置,然后使用fwrite
或fseek
结合ftell
获取定位信息。同时,可以利用rewind
函数将文件指针回到文件起始位置:
void rewind(FILE* stream);
rewind函数等价于执行fseek(stream, 0, SEEK_SET)
。
在读取文件数据时,需要判断文件是否已经读取完毕。feof
函数用于检查此时文件是否结束,但需要注意的是,feof
并不直接判断文件是否读取结束,而是返回文件操作函数(如fgetc
)已经无法读取数据的条件。常见的判断方法包括:
fgetc
返回EOF
fgets
返回NULL
fread
返回0
且没有读取任何数据此外,可以使用ferror
函数检查文件操作是否失败:
if (ferror(stream)) { printf("文件操作失败\n");}
通过这些方法,可以在程序中正确处理文件读取结束的情况。
文件操作是计算机编程中非常重要的一环。理解文件的分类、操作流程以及相关函数的使用,是编程实践中不可或缺的一部分。通过掌握这些知识,可以有效地实现文件的读写、随机访问以及其他高级操作,从而充分发挥文件资源的潜力。
转载地址:http://cdemz.baihongyu.com/