在C++程序开发中,将数据持久化存储到本地文件是非常常见的需求,无论是保存程序配置、记录运行日志还是存储业务数据,都需要用到文件写入相关的操作。C++标准库提供了完善的文件操作支持,开发者可以通过简单的代码实现不同格式、不同场景下的文件写入需求。

C++文件写入的基础类
C++中处理文件操作主要依赖fstream头文件提供的三个类,其中和写入直接相关的是ofstream和fstream:
ofstream:输出文件流类,专门用于向文件写入数据,默认以输出模式打开文件,是最常用的写入类。fstream:通用文件流类,既可以读文件也可以写文件,需要手动指定打开模式。ifstream:输入文件流类,仅用于读取文件,一般不用于写入场景。
文本文件的写入方法
使用ofstream写入文本
这是最基础的文本写入方式,流程和控制台输出类似,只是输出目标从控制台变成了文件。首先需要包含fstream头文件,然后创建ofstream对象并关联目标文件,之后就可以像使用cout一样向文件写入内容。
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// 创建ofstream对象,关联test.txt文件,默认以输出模式打开
ofstream outFile("test.txt");
// 判断文件是否成功打开
if (!outFile.is_open()) {
cout << "文件打开失败" << endl;
return 1;
}
// 向文件写入内容
outFile << "这是第一行写入的内容" << endl;
outFile << "这是第二行写入的内容" << endl;
// 写入整数和浮点数
int num = 100;
double score = 95.5;
outFile << "数字:" << num << ",分数:" << score << endl;
// 关闭文件
outFile.close();
return 0;
}
使用fstream写入文本
如果需要同时支持读写操作,可以使用fstream类,此时需要显式指定打开模式为ios::out,表示以输出模式打开文件。
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// 使用fstream打开文件,指定输出模式
fstream file("data.txt", ios::out);
if (!file.is_open()) {
cout << "文件打开失败" << endl;
return 1;
}
file << "使用fstream写入的文本行" << endl;
file << "支持多种数据类型的写入" << endl;
file.close();
return 0;
}
二进制文件的写入方法
当需要写入非文本内容,比如自定义结构体、图片数据等时,需要使用二进制写入模式,此时要指定打开模式为ios::binary,并且使用write方法完成写入。
#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
// 定义自定义结构体
struct Student {
int id;
char name[20];
double grade;
};
int main() {
// 以二进制输出模式打开文件
ofstream binFile("student.bin", ios::binary);
if (!binFile.is_open()) {
cout << "二进制文件打开失败" << endl;
return 1;
}
// 创建结构体对象并赋值
Student stu;
stu.id = 1;
strcpy(stu.name, "张三");
stu.grade = 88.5;
// 写入二进制数据,第一个参数是数据地址,第二个是数据大小
binFile.write((char*)&stu, sizeof(Student));
binFile.close();
return 0;
}
常用的文件打开模式
在打开文件时,可以通过按位或运算符组合不同的打开模式,满足不同的写入需求,常用的模式如下:
| 模式标识 | 含义说明 |
|---|---|
| ios::out | 输出模式,默认会清空原有文件内容,如果文件不存在则创建 |
| ios::app | 追加模式,写入的内容会添加到文件末尾,不会清空原有内容 |
| ios::binary | 二进制模式,用于非文本文件的读写 |
| ios::trunc | 截断模式,打开文件时清空原有内容,和ios::out默认行为一致 |
| ios::ate | 打开文件后定位到文件末尾,但后续写入可以移动到其他位置 |
追加写入示例
如果需要在不删除原有内容的前提下向文件添加新内容,可以使用ios::app模式:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// 以追加模式打开文件
ofstream logFile("log.txt", ios::app);
if (!logFile.is_open()) {
cout << "日志文件打开失败" << endl;
return 1;
}
logFile << "2024-05-20 10:30:00 程序启动成功" << endl;
logFile << "2024-05-20 10:31:00 用户登录成功" << endl;
logFile.close();
return 0;
}
写入过程中的注意事项
- 每次写入操作完成后,建议显式调用
close方法关闭文件,虽然程序结束时会自动关闭,但显式关闭可以及时释放资源,避免数据丢失。 - 写入前一定要判断文件是否成功打开,避免向无效的文件流写入数据导致程序异常。
- 二进制写入时,要保证写入的数据类型是POD类型(普通旧数据类型),否则可能出现数据对齐、指针失效等问题,导致读取时数据错误。
- 如果需要写入大量数据,可以适当使用
flush方法手动刷新缓冲区,确保数据及时写入文件,避免程序异常退出时缓冲区数据丢失。
文件写入操作属于IO操作,性能比内存操作低很多,如果频繁写入少量数据,建议先缓存到内存中,再一次性写入文件,提升程序运行效率。