C语言文件读写操作详解
文件操作是C语言编程中的基本功能之一。通过文件读写,程序可以与外部存储设备进行数据交互,保持数据的持久性。本文将详细介绍C语言中的文件操作,包含文件读写的基本概念、缓冲区、常用函数以及实际应用示例。
1. 数据流与缓冲区
数据流(Stream)
在C语言中,数据流是指从程序中输入或输出字节的字节流。程序与文件的交互都是通过流的形式进行的。操作文件时,通常需要通过以下步骤来管理数据流:
- 打开文件:打开数据流,准备读取或写入数据。
- 关闭文件:关闭数据流,释放资源。
缓冲区(Buffer)
缓冲区是一块临时存储空间,用于提高文件读写的效率。由于内存存取速度远高于磁盘存取速度,文件操作中,系统会将数据先存放到内存的缓冲区中,减少直接与磁盘的交互。例如:
- 读取文件时,数据首先从磁盘加载到缓冲区,程序从缓冲区读取所需数据。
- 写入文件时,数据先存储在缓冲区,当缓冲区满或文件关闭时,数据才会真正写入磁盘。
2. 文件类型与存取方式
文件类型
- 文本文件:以字符编码形式保存,常见的文本文件如
.txt
。 - 二进制文件:直接保存内存中的数据,适合存储非文本类型的数据,如图片、音频等。
文件存取方式
- 顺序存取:从文件的开头顺序读取或写入数据,适用于大部分文本文件。
- 随机存取:可以在文件的任意位置进行读写操作,常用于二进制文件。
3. C语言文件操作函数
文件的打开与关闭
-
fopen()
:用于打开文件。常见的打开模式有:"r"
:以只读模式打开文本文件。"w"
:以只写模式打开文本文件,若文件不存在则新建。"a"
:以追加模式打开文本文件,在文件末尾写入新数据。
示例:
FILE *fp = fopen("example.txt", "r"); if (fp == NULL) { perror("Error opening file"); return -1; }
-
fclose()
:用于关闭文件流,释放相关资源。fclose(fp);
文件的读写
-
读取操作:
fgetc()
:读取一个字符。fgets()
:读取一行字符串。fread()
:读取指定字节数的二进制数据。
示例(读取一个字符):
int ch = fgetc(fp); while (ch != EOF) { putchar(ch); ch = fgetc(fp); }
-
写入操作:
fputc()
:写入一个字符。fputs()
:写入一个字符串。fwrite()
:写入二进制数据。
示例(写入字符串):
FILE *fp = fopen("output.txt", "w"); if (fp != NULL) { fputs("Hello, World!", fp); fclose(fp); }
文件指针操作
-
fseek()
:移动文件指针到指定位置。常用定位方式包括:SEEK_SET
:文件开头。SEEK_CUR
:当前位置。SEEK_END
:文件末尾。
示例:
fseek(fp, 0, SEEK_SET); // 文件指针移到开头
-
ftell()
:返回当前文件指针的位置。long pos = ftell(fp);
-
rewind()
:将文件指针重置到文件开头。rewind(fp);
4. 实际应用示例
文件复制
以下代码演示了如何将一个文件的内容复制到另一个文件:
FILE *src = fopen("source.txt", "r");
FILE *dst = fopen("destination.txt", "w");
if (src == NULL || dst == NULL) {
perror("Error opening files");
return -1;
}
char buffer[1024];
size_t bytesRead;
while ((bytesRead = fread(buffer, 1, sizeof(buffer), src)) > 0) {
fwrite(buffer, 1, bytesRead, dst);
}
fclose(src);
fclose(dst);
文件行数统计
统计一个文本文件中有多少行:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return -1;
}
int count = 0;
char ch;
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n') {
count++;
}
}
fclose(fp);
printf("The file has %d lines.\n", count);
结语
C语言提供了丰富的文件操作函数,能够有效地实现文件的读写、定位以及状态查询。在编写文件操作程序时,合理使用这些函数可以帮助提高程序的效率和可靠性。