1 / 46

15 檔案管理

15.1 磁碟檔案 15-2 15.1.1 什麼是檔案 15-2 15.1.2 檔案名稱 15-2 15.1.3 開啟檔案 open 15-3 15.1.4 檔案是否開啟成功 15-6 15.1.5 關閉檔案 close 15-7 15.2 存取文字檔 15-7 15.2.1 寫入文字檔 << 15-8 15.2.2 附加資料到文字檔 << 15-9 15.2.3 讀取文字檔 >> 15-11 15.2.4 寫入單一字元 put 15-12 15.2.5 讀取單一字元 get 15-13.

sonya-berg
Download Presentation

15 檔案管理

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 15.1磁碟檔案 15-2 15.1.1 什麼是檔案 15-2 15.1.2 檔案名稱 15-2 15.1.3 開啟檔案open 15-3 15.1.4 檔案是否開啟成功 15-6 15.1.5 關閉檔案close 15-7 15.2存取文字檔 15-7 15.2.1 寫入文字檔 << 15-8 15.2.2 附加資料到文字檔 << 15-9 15.2.3 讀取文字檔 >> 15-11 15.2.4 寫入單一字元put 15-12 15.2.5 讀取單一字元get 15-13 15.3存取二進位檔 15-17 15.3.1 寫入二進位檔write 15-17 15.3.2 附加資料到二進位檔write 15-19 15.3.3 讀取二進位檔read 15-22 15.3.4 檔案結束位置eof 15-24 15.4隨機存取資料 15-28 15.4.1 移動讀取指標seekg 15-29 15.4.2 移動寫入指標seekp 15-29 15.4.3 取得讀取指標tellg 15-32 15.4.4 取得寫入指標tellp 15-32 15 檔案管理

  2. 15.1 磁碟檔案 • 因為結束程式或關閉電源都將使得存在記憶體中的資料消失,所以每次執行前幾章的學生資料程式或員工資料程式時,都必須重新輸入資料。 • 如果經常要使用這些資料,則可以在結束程式或關閉電源以前將資料存入磁碟檔案中,下次要用時再從磁碟檔案中讀取。

  3. 15.1.1 什麼是檔案 • 在許多程式中,檔案(file)是基本的輸入與輸出物件。檔案物件(file object)收集了磁碟檔案資訊,包括檔案是否存在或開啟,以及存取檔案的路徑、大小、日期、與時間等等,所以可以利用檔案物件開啟、讀取、寫入、關閉、與取得磁碟檔案的資料。

  4. 15.1.2 檔案名稱 • 所有的檔案都有一個可讓作業系統與使用者確認的獨一無二的檔名。每個作業系統都有它們自己的檔案命名方式,例如Windows可以接受長檔名,而MS-DOS則只接受短檔名(主檔名8個字元,副檔名3個字元)。 • 基本上檔名分為主檔名與副檔名,而且主檔名與副檔名中間以句點(.)隔開。一般而言,副檔名代表檔案的種類。

  5. 15.1.2 檔案名稱 (續)

  6. 15.1.3 開啟檔案open • #include <fstream.h> • ifstream 輸入物件; //建立輸入檔案物件ofstream 輸出物件; //建立輸出檔案物件fstream 輸出入物件; //建立輸入輸出檔案物件 • 檔案物件.open(“檔案名稱”, ios::開啟模式);

  7. 15.1.3 開啟檔案open (續)

  8. 15.1.3 開啟檔案open (續) • 先建立檔案物件,再開啟資料檔 ofstream out; //建立輸出檔案物件 ifstream in; //建立輸入檔案物件 fstream io; //建立輸入輸出檔案物件 out.open("a:\\textOut.txt", ios::out); //開啟輸出檔案 in.open("a:\\textIn.txt", ios::in); //開啟輸入檔案 io.open("a:\\textIO.txt", ios::in|ios::out); //開啟輸入輸出檔案

  9. 15.1.3 開啟檔案open (續) • 先建立檔案物件,再開啟二進位檔案 ofstream out; //建立輸出檔案物件 ifstream in; //建立輸入檔案物件 fstream io; //建立輸入輸出檔案物件 out.open("textOut.txt", ios::binary|ios::out); //開啟二進位輸出檔案 in.open("textIn.txt", ios::binary|ios::in); //開啟二進位輸入檔案 io.open("textIO.txt", ios::binary|ios::in|ios::out); //開啟二進位輸入輸出

  10. 15.1.3 開啟檔案open (續) • 建立同時開啟資料檔案 //使用ofstream的建立者函數建立物件並開啟輸出檔案 • ofstream out("a:\\textOut.dat", ios::out); //使用ifstream的建立者函數建立物件並開啟輸入檔案 • ifstream in("a:\\textIn.dat", ios::in); //使用fstream的建立者函數建立物件並開啟輸入輸出檔案 • fstream io("a:\\textIO.dat", ios::in, ios::out);

  11. 15.1.3 開啟檔案open (續) • 建立同時開啟二進位檔案 //使用ofstream的建立者函數建立物件並開啟輸出檔案 • ofstream out("a:\\textOut.dat", ios::binary|ios::out); //使用ifstream的建立者函數建立物件並開啟輸入檔案 • ifstream in("a:\\textIn.dat", ios::binary|ios::in); //使用fstream的建立者函數建立物件並開啟輸入輸出檔案 • fstream io("a:\\textIO.dat", ios::binary|ios::in|ios::out);

  12. 15.1.4 檔案是否開啟成功 • 在呼叫open函數後,必須先測試檔案是否開啟成功,然後才可正確存取檔案資料。 ifstream myFile; //建立輸入檔案物件 in.open("a:\\textIn.txt", ios::in); //開啟輸入檔案 if(!myFile) //測試檔案是否開啟成功 cout << "開啟檔案失敗!\n"; //檔案代號錯誤

  13. 15.1.4 檔案是否開啟成功 (續) • 當使用建立者函數建立檔案物件並開啟檔案時,則可用is_open() 函數來判斷檔案開啟是否成功 ifstream myFile("a:\\textIn.txt", ios::in); //建立並開啟檔案 if(!myFile.is_open())//測試檔案是否開啟成功 cout << "開啟檔案失敗!\n"; //檔案代號錯誤

  14. 15.1.5 關閉檔案close • #include <fstream> • 物件名稱.close(); • 範例 myFile.close(); //關閉myFile檔案物件

  15. 15.2 存取文字檔 • 一般文字編輯軟體都是將資料存入文字檔,例如微軟的NotePad就是將文件存入 .txt檔,而WordPad與Word則是將文件存入 .doc檔。所以本節將要介紹如何寫入資料至文字檔、如何附加資料到文字檔、與讀取文字檔資料等等。

  16. 15.2.1 寫入文字檔 << • 物件名稱.open(“檔案名稱”, ios::out); //開啟檔案 • 物件名稱 << 輸出字串; //寫入檔案 • 範例一 ofstream filePtr; //建立檔案物件filePtr filePtr.open("a:\\textIO.txt", ios::out);//開啟檔案a:\textIO.txt filePtr << "Life is not easy, but in the long run \n"; filePtr << "it's easier than going to elaborate ends \n"; filePtr << "to deny it.\n"; //寫入字串到檔案 filePtr.close(); //關閉filePtr檔案物件

  17. 15.2.1 寫入文字檔 << (續) • 範例二 int id; //宣告整數變數 char name[40]; //宣告C型態字串變數 ofstream outFile; //建立檔案物件outFile outFile.open(“a:\\textIO.dat”, ios::out); //開啟檔案a:\textIO.dat cin >> id >> name; //從鍵盤讀取整數與字串 outFile << id << '\t' << name << '\n'; //寫入整數與字串到檔案 outFile.close(); //關閉outFile檔案物件

  18. 15.2.2 附加資料到文字檔 << • 物件名稱.open(“檔案名稱”, ios::app); //開啟檔案 • 物件名稱 << 字串1 << 字串2; //附加資料 • 範例一 ofstream filePtr; //建立檔案物件filePtr filePtr.open("a:\\outFile.txt", ios::app); //開啟a:\outFile.txt filePtr << "人生的確不是簡單的,可是老老實實地活著, \n"; //附加字串到檔案 filePtr << "總要比想出千方百計的逃避人生來得簡單些。 \n"; //附加字串到檔案 filePtr.close();

  19. 15.2.2 附加資料到文字檔 << (續) • 範例二 int id; //宣告整數變數 char name[40]; //宣告C型態字串變數 ofstream outFile; //建立檔案物件outFile outFile.open("a:\\textIO.dat", ios::app); //開啟檔案a:\textIO.dat cin >> id >> name; //從鍵盤讀取整數與字串 outFile << id << '\t' << name << '\n'; //寫入整數與字串到檔案 outFile.close(); //關閉outFile檔案物件

  20. 15.2.3 讀取文字檔 >> • 物件名稱.open(“檔案名稱”, ios::in);//開啟檔案 • 物件名稱 >> 緩衝區1 >> 緩衝區2; //讀取資料 • 範例 ifstream outFile; //建立檔案物件outFile int id; //存放資料緩衝區 char name[40]; //存放資料緩衝區 • 範例待續……

  21. 15.2.3 讀取文字檔 >> (續) outFile.open("a:textIO.dat", ios::in); //開啟輸入檔a:\textIO.dat outFile >> id >> name; //讀取檔案存入緩衝區 while(!outFile.eof()) { //是否已到檔尾 cout << id << '\t' << name << endl; //顯示緩衝區資料 outFile >> id >> name; //讀取檔案存入緩衝區 } outFile.close(); //關閉檔案物件outFile

  22. 15.2.4 寫入單一字元put • 物件名稱.open(“檔案名稱”, ios::out); //開啟檔案 • 物件名稱.put(字元緩衝區); //寫入資料 • 範例 ofstream filePtr; //建立檔案物件filePtr char inData[] = "Life is not easy, but in the long run \n" "it's easier than going to elaborate ends \n" "to deny it.\n"; • 範例待續……

  23. 15.2.4 寫入單一字元put (續) • 範例續 filePtr.open("a:\\textIO.txt", ios::in); //開啟輸入檔a:\textIO.txt int len = strlen(inData); //取得inData陣列的長度 for(int i=0; i<len; i++) { //寫入字元迴圈 filePtr.put(inData[i]); //寫入字元到textIO.txt } filePtr.close(); //關閉檔案物件filePtr

  24. 15.2.5 讀取單一字元get • 物件名稱.open(“檔案名稱”, ios::in); //開啟檔案 • 物件名稱.get(字元緩衝區); //讀取資料 • 範例 ifstream filePtr; //建立檔案物件filePtr char inData; //存放資料緩衝區 filePtr.open("a:\\textIO.txt", ios::in); //開啟輸出檔a:\textIO.txt while(filePtr.get(inData)) { //取得資料並存入緩衝區 cout << inData; //顯示資料 } filePtr.close(); //關閉檔案物件filePtr

  25. Exercise • 用C++寫一個檔案複製的程式 • 下載f1.txt • 寫一個程式,利用檔案讀取及檔案寫入的方式,將f1.txt複製為f2.txt

  26. 15.3 存取二進位檔 • 雖然讀寫格式化的文字檔非常簡單,也非常適用於文件檔案的存取,但它不是最有效的檔案管理方式。所以現在要介紹另一種的檔案管理方式:非格式化的二進位檔。

  27. 15.3.1 寫入二進位檔write • 物件名稱.open(“檔案名稱”, ios::binary); //開啟二進位檔 • 物件名稱.write(const char *緩衝區, 寫入長度);//寫入資料 • 範例 class Student { //自定Student資料 int student_id; char student_name[40]; public: Student() { Student_id = 10; Student_name = "Tom"; } };

  28. 15.3.1 寫入二進位檔write (續) • 範例續 int main() { Student stuData; //建立類別物件 ofstream filePtr; //建立輸出檔案物件 filePtr.open("a:\\binIO.dat", ios::binary|ios::out); //開啟二進位檔 filePtr.write((char*)&stuData, sizeof(stuData)); //緩衝區資料寫入檔案 filePtr.close(); return 0; //正常結束程式 }

  29. 15.3.2 附加資料到二進位檔write • 物件名稱.open(“檔案名稱”, ios::binary | ios::app); • 物件名稱.write(const char *緩衝區, 寫入長度); class Student { //自定Student資料 int student_id; char student_name[40]; public: setData(id, name) { student_id = id; student_name = name; } };

  30. 15.3.2 附加資料到二進位檔write (續) • 範例續 int main() { Student stuData; //建立類別物件 ofstream filePtr; //建立輸出檔案物件 filePtr.open("a:\\binIO.dat ", ios::binary|ios::app); //開啟二進位附加檔 stuData.setData(1, "Ken"); //設定自定資料 filePtr.write((char*)&stuData, sizeof(stuData)); //緩衝區資料附加到檔案 filePtr.close(); return 0; //正常結束程式 }

  31. 15.3.3 讀取二進位檔read • 物件名稱.open(“檔案名稱”, ios::binary | ios::in); • 物件名稱.read(const char *緩衝區, 讀取長度); • 範例 class Student { //自定Student資料 int student_id; char student_name[40]; public: void showData() { cout << student_id << '\t' << student_name << endl; } };

  32. 15.3.3 讀取二進位檔read (續) • 範例續 int main() { Student stuData; //建立類別物件 ifstream filePtr; //建立輸出檔案物件 filePtr.open("a:\\binIO.dat", ios::binary|ios::in); filePtr.read((char*)&stuData, //讀取資料到緩衝區 sizeof(stuData)); //讀取長度=緩衝區大小 stuData.showdata(); //呼叫顯示資料函數 filePtr.close(); return 0; //正常結束程式 }

  33. 15.3.4 檔案結束位置eof • 輸入檔案物件.eof() • 範例 class Student { // 自定Student資料 int student_id; char student_name[40]; public: void showData() { cout << student_id << '\t' << student_name << endl; } };

  34. 15.3.4 檔案結束位置eof (續) • 範例續 int main() { Student stuData; //建立類別物件 ifstream filePtr; //建立輸出檔案物件 filePtr.open("a:\\binIO.dat", ios::binary|ios::in); //開啟二進位附加檔 filePtr.read((char*)&stuData, //讀取資料到緩衝區 sizeof(stuData)); //讀取長度=緩衝區大小

  35. 15.3.4 檔案結束位置eof (續) • 範例續 while(!filePtr.eof()) { //讀取資料迴圈 stuData.showdata(); //呼叫顯示資料函數 filePtr.read((char*) &stuData, //讀取資料到緩衝區 sizeof(stuData)); //讀取長度=緩衝區大小 } filePtr.close(); return 0; //正常結束程式 }

  36. Exercise • 寫一個C++程式處理影像檔 • 下載lena1.raw • 用photoshop瀏覽lena1.raw • 寫一個程式,利用檔案讀取及檔案寫入的方式,將lena1.raw複製為lena2.raw,但請將每一個字元的值c改為(255-c),再寫入lena2.raw • 注意c的型態應改為unsigned char • 用photoshop瀏覽lena2.raw

  37. 15.4 隨機存取資料 • 文字檔是一個字元或一個字串為單位,而二進位檔則是以一筆資料為單位,所以二進位檔案的優點就是可以隨機存取檔案內的資料,也就是說可以任意存取二進位檔中的任何一筆資料。

  38. 15.4.1 移動讀取指標seekg • 輸入檔案物件.seekg(移動距離, ios::起始位置)

  39. 15.4.2 移動寫入指標seekp • 輸出檔案物件.seekp(移動距離, ios::起始位置)

  40. 15.4.2 移動寫入指標seekp (續)

  41. 15.4.2 移動寫入指標seekp (續) class Student { //自定Student資料 int student_id; char student_name[40]; public: void showData() { cout << student_id << '\t' << student_name << endl; } };

  42. 15.4.2 移動寫入指標seekp (續) • 範例續 int main() { Student stuData; //建立類別物件 ifstream filePtr; //建立輸出檔案物件 filePtr.open("a:\\binIO.dat", ios::binary|ios::in); int n; cin >> n; int len = sizeof(stuData); //計算每筆資料長度 int pos = (n-1) * len; //計算第n筆資料位置 filePtr.seekg(pos, ios::beg); //移動get指標 filePtr.read((char*)&stuData, sizeof(stuData));//讀取資料 stuData.showdata(); //呼叫顯示資料函數 filePtr.close(); return 0; //正常結束程式 }

  43. 15.4.3 取得讀取指標tellg • 輸入檔案物件.tellg() 15.4.4 取得寫入指標tellp • 輸出檔案物件.tellp()

  44. 15.4.4 取得寫入指標tellp (續) • 範例一 int main() { ifstream filePtr; //建立輸出檔案物件 filePtr.open("a:\\binIO.dat", ios::binary|ios::in); filePtr.seekg(0, ios::end); //移動指標到檔尾 int endpos = filePtr.tellg(); //取得指標位置 cout << "a:\\binIO.dat 的大小 = " << endpos << " bytes" << endl; //顯示檔案大小 filePtr.close(); return 0; //正常結束程式 }

  45. 15.4.4 取得寫入指標tellp (續) • 範例二 class Student { int student_id; char student_name[40]; }; int main() { ifstream filePtr; //建立輸出檔案物件 filePtr.open("a:\\binIO.dat", ios::binary|ios::in); //開啟二進位輸入檔 filePtr.seekg(0, ios::end); //移動指標到檔尾 int endpos = filePtr.tellg(); //取得檔案位元組數 int n = endpos / sizeof(stuData); //除以緩衝器大小 cout << "a:\\binIO.dat 共有 " << n << " 筆資料"; //顯示資料筆數 filePtr.close(); return 0; //正常結束程式 }

  46. Exercise • 下載C1505.dat • 使用課本範例程式15-09中的class Student • 將C1505.dat中的學生資料依序逐筆印出 • 可參考課本範例程式15-09,10,11的程式內容

More Related