1. 为什么需要文件操作与序列化
在C++开发中,文件操作和序列化是每个程序员必须掌握的基础技能。想象一下你正在开发一个游戏存档系统,或者一个需要持久化配置的应用程序,这些场景都离不开文件读写和对象序列化。
文件操作的本质是程序与外部存储介质的数据交换。当我们需要保存程序状态、记录日志或导入导出数据时,就必须与文件系统打交道。而序列化则是将内存中的对象转换为可以存储或传输的格式(通常是二进制或文本),反序列化则是其逆过程。
提示:在Windows平台上,文件路径使用反斜杠
\需要转义为\\,或者使用C++11引入的原始字符串字面量(R"(path)")。
2. C++标准库文件操作详解
2.1 文件流基础类
C++通过<fstream>头文件提供了三种文件流类:
ifstream:输入文件流,用于读取文件ofstream:输出文件流,用于写入文件fstream:双向文件流,可读可写
基本文件操作模式:
cpp复制#include <fstream>
using namespace std;
// 写入文件
ofstream outFile("data.txt", ios::out | ios::binary);
outFile << "Hello, World!" << endl;
outFile.close();
// 读取文件
ifstream inFile("data.txt");
string line;
while(getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
2.2 二进制与文本模式对比
| 模式 | 特点 | 适用场景 |
|---|---|---|
| 文本模式 | 处理换行符转换 无法精确控制字节 |
配置文件 日志文件 |
| 二进制模式 | 精确字节控制 无格式转换 |
多媒体文件 序列化数据 |
二进制模式示例:
cpp复制struct Person {
char name[20];
int age;
double height;
};
Person p = {"Alice", 25, 165.5};
ofstream binFile("person.dat", ios::binary);
binFile.write(reinterpret_cast<char*>(&p), sizeof(p));
binFile.close();
2.3 文件指针控制
文件流提供了几个关键方法控制读写位置:
tellg()/tellp():获取当前读/写位置seekg()/seekp():设置读/写位置
随机访问示例:
cpp复制fstream file("data.bin", ios::in | ios::out | ios::binary);
file.seekp(1024); // 移动到1KB位置
int value = 42;
file.write(reinterpret_cast<char*>(&value), sizeof(value));
3. 对象序列化实现方案
3.1 简单结构体的序列化
对于POD(Plain Old Data)类型,可以直接内存拷贝:
cpp复制struct SimpleData {
int id;
float values[3];
char tag;
};
void serialize(const SimpleData& data, ostream& out) {
out.write(reinterpret_cast<const char*>(&data), sizeof(data));
}
void deserialize(istream& in, SimpleData& data) {
in.read(reinterpret_cast<char*>(&data),
