核心代碼
#include
#include
#include
int main() {
// 寫入二進制文件
std::ofstream fout("data.bin", std::ios::binary);
if (!fout) {
std::cerr << "無法打開文件寫入\n";
return EXIT_FAILURE;
}
const int N = 20;
for (int i = 0; i <= N; ++i) {
fout.write(reinterpret_cast(&i), sizeof(int));
}
fout.close();
// 讀取二進制文件
std::ifstream fin("data.bin", std::ios::binary);
if (!fin) {
std::cerr << "無法打開文件讀取\n";
return EXIT_FAILURE;
}
int x;
while (fin.read(reinterpret_cast(&x), sizeof(int))) {
std::cout << x << ' ';
}
std::cout << '\n';
fin.close();
return EXIT_SUCCESS;
}
關鍵點解析
| 操作 | 舊式寫法 | 現代標準寫法 |
| 頭文件 | <fstream.h> | <fstream> (std 命名空間) |
| 打開模式 | 默認文本 | std::ios::binary 關鍵:禁用換行轉換 |
| 寫入 | fout << i << ' '; (文本) | fout.write(ptr, size) (二進制) |
| 讀取 | fin >> x; (文本解析) | fin.read(ptr, size) (原始字節) |
| 類型轉換 | C 風格 | reinterpret_cast<char*> 類型安全 |
| 錯誤檢查 | if(!fout) | if(!fout.is_open()) 或流狀態判斷 |
二進制 vs 文本模式
- 文本模式:Windows 下
\n ↔ \r\n 轉換,數值格式化為字符序列,跨平台可讀但空間大、解析慢。
- 二進制模式:字節級精確映射內存表示,無轉換,體積小、讀寫快、跨平台需注意字節序/對齊/類型大小。
進階主題
結構體序列化
struct Record { int id; double value; char name[32]; };
Record rec = {1, 3.14, "test"};
fout.write(reinterpret_cast(&rec), sizeof(Record));
// 注意:結構體填充字節、指針不可直接序列化、跨平台需處理對齊/端序
隨機訪問
fout.seekp(pos, std::ios::beg); // 寫位置
fin.seekg(pos, std::ios::beg); // 讀位置
fin.tellg(); fin.tellp(); // 獲取當前位置
異常安全
try {
std::ofstream fout("data.bin", std::ios::binary | std::ios::trunc);
fout.exceptions(std::ofstream::failbit | std::ofstream::badbit);
// 操作...
} catch (const std::ios_base::failure& e) {
std::cerr << "IO 錯誤: " << e.what() << '\n';
}
最佳實踐清單
- 二進制文件必須加
std::ios::binary。
- 使用
write/read 配合 reinterpret_cast。
- 結構體序列化考慮
#pragma pack、端序轉換、版本號。
- 大數據量分塊讀寫,避免單次分配巨大緩衝區。
- RAII 管理流對象,異常安全。
- 跨平台持久化優先考慮 Protocol Buffers、FlatBuffers、MessagePack 等序列化框架。