本文来自:http://openhome.cc/Gossip/CppGossip/RadomAccessFile.html
使用 get 指標或 put 指標,可以自由的移動至檔案中指定的位置進行讀取或寫入的動作,通常隨機存取檔案會使用二進位模式進行,文字模式開啟的檔案並不適合作隨機存取的動作。 如何利用隨機存取來讀寫所有的資料,必須視您的需求而定,需求決定您的資料結構,這邊以一個最簡單的例子來示範隨機存取,寫入檔案時都是使用固定大小的struct,由於資料大小固定,這可以方便明確的指定檔案中讀取的位置。 假設有一個簡單的學生成績資料如下:
#ifndef DATASTRU_H #define DATASTRU_H struct Student { int studyNumber; char name[80]; double score; }; #endif 一個結構的大小是固定的,當要寫入一個結構時,可以使用這樣的語法: fout.write(reinterpret_cast<const char*> (&student),
sizeof(Student));
#include <iostream> #include <fstream> #include "Student.h" using namespace std; int main(int argc, char* argv[]) { if(argc != 2) { cout << "指令: create <filename>" << endl; return 1; } ofstream fout(argv[1], ios::binary); if(!fout) { cerr << "檔案輸出失敗" << endl; return 1; } int count; cout << "要建立幾筆資料? "; cin >> count; Student student = {0, "", 0.0}; for(int i = 0; i < count; i++) { fout.write(reinterpret_cast<const char*> (&student), sizeof(Student)); } fout.close(); return 0; } 執行結果:
接下來可以使用下面這個程式進行隨機存取,使用學號來作資料的位置指定,將之儲存在檔案中的指定位置: #include <iostream> #include <fstream> #include "Student.h" using namespace std; int main(int argc, char* argv[]) { Student student; int count = 0; if(argc < 2) { cerr << "指令: write <filename>"; return 1; } fstream fio(argv[1], ios::in | ios::out | ios::binary); if(!fio) { cerr << "無法讀取檔案" << endl; return 1; } while(true) { fio.read(reinterpret_cast<char *> (&student), sizeof(Student)); if(!fio.eof()) count++; else break; } fio.clear(); cout << "輸入學號(1-" << count << ")" << endl << "輸入0離開"; while(true) { cout << "n學號? "; cin >> student.studyNumber; if(student.studyNumber == 0) break; cout << "輸入姓名, 分數" << endl << "? "; cin >> student.name >> student.score; fio.seekp((student.studyNumber - 1) * sizeof(Student)); fio.write(reinterpret_cast<const char*> (&student), sizeof(Student)); } fio.close(); return 0; } 執行結果:
接下來可以使用下面這個程式讀取方才所輸入的資料: #include <iostream> #include <fstream> #include "Student.h" using namespace std; int main(int argc, char* argv[]) { Student student; int count = 0, number; if(argc != 2) { cout << "指令: read <filename>" << endl; return 1; } ifstream fin(argv[1], ios::in | ios::binary); if(!fin) { cerr << "無法讀取檔案" << endl; return 1; } while(true) { fin.read(reinterpret_cast<char *> (&student), sizeof(Student)); if(!fin.eof()) count++; else break; } fin.clear(); cout << "輸入學號(1-" << count << ")" << endl << "輸入0離開"; while(true) { cout << "n學號? "; cin >> number; if(number == 0) break; else if(number > count) { cout << "輸入學號(1-" << count << ")" << endl; continue; } cout << "n學號t姓名tt分數" << endl; fin.seekg((number - 1) * sizeof(Student)); fin.read(reinterpret_cast<char*> (&student), sizeof(Student)); cout << student.studyNumber << "t" << student.name << "tt" << student.score << endl; } fin.close(); return 0; } 執行結果:
這幾個程式是隨機存取的簡單示範,您也可以結合起來,製作一個簡易的成績登記程式。 file.seekg(0, ios::end);
count = file.tellg() / sizeof(資料結構); |
|