二進位檔案將記憶體資料原樣位元對位元寫入磁碟,無 ASCII 轉換開銷,故稱記憶體映像檔或位元組檔。優勢明顯:
打開需指定 ios::binary 模式,且可同時為輸入/輸出檔(fstream 類別)。
// 寫入:從記憶體位址 p1 寫入 50 位元組到檔案 outfile.write(p1, 50); // 讀取:從檔案讀 30 位元組到記憶體位址 p2 infile.read(p2, 30);
參數為 char* 指標與位元組數,需以 (char*) 強制轉型結構體位址。
struct Student { char name[20]; int num, age; char sex; };
Student stud[3] = {{"Li",1001,18,'f'}, {"Fun",1002,19,'m'}, {"Wang",1004,17,'f'}};
ofstream outfile("stud.dat", ios::binary);
for (int i=0; i<3; ++i)
outfile.write((char*)&stud[i], sizeof(stud[i]));
// 或一次寫入全部:
// outfile.write((char*)&stud[0], sizeof(stud));
outfile.close();
ifstream infile("stud.dat", ios::binary);
Student stud[3];
for (int i=0; i<3; ++i)
infile.read((char*)&stud[i], sizeof(stud[i]));
// 顯示邏輯...
infile.close();
關鍵:讀取格式必須與寫入格式完全匹配(同結構體配置),否則資料錯位。
| 函式 | 用途 |
|---|---|
tellg() / tellp() | 取得輸入/輸出指標當前位置(位元組偏移) |
seekg(pos) / seekp(pos) | 將指標移至絕對位置 |
seekg(off, dir) / seekp(off, dir) | 相對移動:ios::beg開頭、ios::cur目前、ios::end結尾 |
記憶口訣:g=get(輸入)、p=put(輸出)。
fstream iofile("stud.dat", ios::in|ios::out|ios::binary);
// 1. 寫入 5 筆初始資料
for (int i=0; i<5; ++i) iofile.write((char*)&stud[i], sizeof(stud[i]));
// 2. 讀取第 1,3,5 筆(索引 0,2,4)
for (int i=0; i<5; i+=2) {
iofile.seekg(i * sizeof(Student), ios::beg);
iofile.read((char*)&stud1[i/2], sizeof(Student));
cout << stud1[i/2].num << ' ' << stud1[i/2].name << ' ' << stud1[i/2].score << endl;
}
// 3. 修改第 3 筆(索引 2)並寫回原位
stud[2] = {1012, "Wu", 60};
iofile.seekp(2 * sizeof(Student), ios::beg);
iofile.write((char*)&stud[2], sizeof(Student));
// 4. 重頭讀取驗證
iofile.seekg(0, ios::beg);
for (int i=0; i<5; ++i) {
iofile.read((char*)&stud[i], sizeof(Student));
cout << stud[i].num << ' ' << stud[i].name << ' ' << stud[i].score << endl;
}
iofile.close();
fstream,ifstream/ofstream 不支援雙向操作string 等動態型別),否則跨平台/版本會錯位sizeof(元素) 為單位,確保精準定位二進位檔案配合 read/write 與指標控制,實現高效、隨機存取的資料持久化,是資料庫引擎、遊戲存檔、高效能日誌系統的基石技術。