文件IO操作

1. 核心头文件与流对象
C++ 实现文件读写必须包含 <fstream> 头文件,该头文件提供了 3 个核心的文件流类,用于不同的文件操作场景:
| 流类名 |
功能说明 |
核心操作方向 |
ifstream |
专门用于从文件读取数据 |
输入(读) |
ofstream |
专门用于向文件写入数据 |
输出(写) |
fstream |
既可读又可写文件 |
输入 + 输出 |
2. 文件打开模式
文件打开时需要指定模式,决定文件的操作规则,可通过 open() 函数或流对象构造函数指定,多个模式用 | 分隔:
| 模式常量 |
功能说明 |
ios::in |
以只读方式打开文件;若文件不存在,打开失败 |
ios::out |
以只写方式打开文件;若文件不存在则自动创建,若文件已存在则清空原有内容 |
ios::app |
追加模式;写入的所有数据都会添加到文件末尾,不会清空原有内容 |
ios::trunc |
截断模式;若文件已存在,打开时清空所有内容(ios::out 模式默认包含此特性) |
ios::binary |
二进制模式;按字节流读写(默认是文本模式,会处理换行符等特殊字符) |
ios::ate |
打开文件后,文件指针直接定位到文件末尾(可后续移动指针) |
3. 文件路径规则
- Windows 系统:路径中的反斜杠需要转义(如
C:\\test\\demo.txt),或直接使用正斜杠(C:/test/demo.txt);
- Linux/Mac 系统:直接使用正斜杠(
/home/user/demo.txt);
- 相对路径:以程序运行目录为基准(如
./demo.txt 表示当前目录,../demo.txt 表示上级目录)。
二、C++ 文件 IO 基础操作(文本文件)
1. 写入文件(ofstream)
核心流程:定义流对象 → 打开文件 → 检查是否打开成功 → 写入数据 → 关闭文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <iostream>
#include <fstream>
#include <string> using namespace std;
int main() { ofstream outFile;
outFile.open("demo.txt", ios::out);
if (!outFile.is_open()) { cout << "文件打开失败,请检查路径是否正确!" << endl; return 1; }
outFile << "C++文件IO写入测试" << endl; outFile << "整数:" << 100 << " 浮点数:" << 3.1415 << endl; string str = "这是字符串内容"; outFile << str << endl;
outFile.close();
return 0; }
|
实际开发会将文件写入指定位置,而不是默认在同级目录下
1 2 3 4 5
| string filename = "D:\\data\\txt\\test.txt";
ofstream fout;
fout.open(filename);
|
文件打开失败的主要原因:
2. 读取文件(ifstream)
读取文件有 3 种常用方式,适配不同场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include <iostream> #include <fstream> #include <string> using namespace std;
int main() { ifstream inFile("demo.txt", ios::in); if (!inFile) { cout << "文件打开失败!" << endl; return 1; }
cout << "【逐字符读取】:" << endl; char ch; while (inFile.get(ch)) { cout << ch; } cout << endl; inFile.clear(); inFile.seekg(0);
cout << "【按行读取】:" << endl; string line; while (getline(inFile, line)) { cout << line << endl; } inFile.clear(); inFile.seekg(0);
cout << "【按单词读取】:" << endl; string word; while (inFile >> word) { cout << word << " "; } cout << endl;
inFile.close(); return 0; }
|
3. 追加写入文件(ios::app)
若不想清空原有文件,仅在末尾添加内容,使用 ios::app 模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <iostream> #include <fstream> using namespace std;
int main() { ofstream outFile("demo.txt", ios::app); if (!outFile) { cout << "文件打开失败!" << endl; return 1; }
outFile << "这是追加的内容,不会覆盖原有内容" << endl; outFile.close();
return 0; }
|
三、二进制文件操作
二进制文件(如图片、视频、自定义结构体数据)不能用文本模式读写,需指定 ios::binary 模式,核心用 read()/write() 函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream> #include <fstream> using namespace std;
struct Student { char name[20]; int age; float score; };
int main() { Student s1 = {"李明", 19, 88.9}; ofstream outFile("student.dat", ios::out | ios::binary); if (!outFile) { cout << "文件打开失败!" << endl; return 1; } outFile.write((char*)&s1, sizeof(Student)); outFile.close();
Student s2; ifstream inFile("student.dat", ios::in | ios::binary); if (!inFile) { cout << "文件打开失败!" << endl; return 1; } inFile.read((char*)&s2, sizeof(Student)); cout << "姓名:" << s2.name << endl; cout << "年龄:" << s2.age << endl; cout << "分数:" << s2.score << endl; inFile.close();
return 0; }
|
四、文件指针与随机访问
默认情况下,文件读写是顺序的,可通过文件指针实现随机读写:
seekg():调整输入流(读)的指针位置(g=get);
seekp():调整输出流(写)的指针位置(p=put);
指针偏移量:从基准位置开始的字节数,基准位置有 3 种:
ios::beg:文件开头;
ios::cur:当前指针位置;
ios::end:文件末尾。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <iostream> #include <fstream> #include <string> using namespace std;
int main() { fstream file("demo.txt", ios::in | ios::out); if (!file) { cout << "文件打开失败!" << endl; return 1; }
file.seekg(5, ios::beg); string content; file >> content; cout << "从第6字节开始的内容:" << content << endl;
file.seekg(-10, ios::end); file >> content; cout << "文件末尾前10字节开始的内容:" << content << endl;
long pos = file.tellg(); cout << "当前指针位置:" << pos << " 字节" << endl;
file.close(); return 0; }
|
五、常见注意事项
- 文件打开检查:无论哪种操作,必须先检查文件是否打开成功(
is_open() 或直接判断流对象),否则后续操作会无意义且可能崩溃;
- 流状态管理:读取文件到末尾后,流会进入错误状态,需用
clear() 清空状态才能重新读取;
- 编码问题:C++ 无统一文件编码标准,Windows 系统默认 GBK,Linux/Mac 默认 UTF-8,读写中文时需保证编码一致;
- 大文件处理:避免一次性读取全部内容,优先用逐行 / 逐块读取(如
getline()),减少内存占用;
- 文件关闭:虽然流对象析构时会自动关闭文件,但显式调用
close() 是最佳实践,可及时释放文件资源。
总结
- C++ 文件 IO 核心依赖
<fstream> 头文件,通过 ifstream(读)、ofstream(写)、fstream(读写)实现文件操作,核心流程是定义流对象→打开文件→检查状态→操作数据→关闭文件;
- 打开模式决定文件行为:
ios::out 清空创建、ios::app 追加、ios::binary 处理二进制文件;
- 文本文件用
<</>>/getline() 读写,二进制文件用 read()/write(),seekg()/seekp() 可实现文件指针的随机定位。