本文来自: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(資料結構); |
|