File Handling In Pascal/zh TW: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: File Handling In Pascal/zh TW
| Old | New | Line | |
|---|---|---|---|
| 1 | + | 大概所有程式設計師最需要知道的就是如何處理檔案。檔案可以用來儲存使用者的設定,錯誤報告,或更多更多。在這裡我們將教您一些最基本的文字檔案處理。 | |
| 2 | + | ||
| 3 | + | # 舊方法 | |
| 4 | + | ||
| 5 | + | 當使用傳統非物件導向的 Pascal 時,你可以使用 TextFile 類型 (type),可以讓你建立檔案並對它寫入字串。 | |
| 6 | + | ||
| 7 | + | ``` pascal | |
| 8 | + | ... | |
| 9 | + | type | |
| 10 | + | TIntegerFile = file of Integer; // 可以讓你對檔案寫入整數值 | |
| 11 | + | TPCharFile = file of PChar; // 將字元 (PChars) 寫入檔案 :\ | |
| 12 | + | TStringFile = file of string; // 將字串寫入檔案 | |
| 13 | + | ... | |
| 14 | + | ``` | |
| 15 | + | ||
| 16 | + | 若我們僅用了 TStringFile = File,它將無法寫入任何東西!更無法將整數值寫入 TStringFile,因為它已經是字串型態的檔案。最好是使用 TextFile 的型態,它才能寫入各種不同形態的內容。 | |
| 17 | + | ||
| 18 | + | ## 輸入輸出 | |
| 19 | + | ||
| 20 | + | IO 是 Pascal 專門用來處理檔案用的。他通常用來對付錯誤訊息。 當用來當編譯器的指令時,你可以這麼用: | |
| 21 | + | ||
| 22 | + | ``` pascal | |
| 23 | + | {$I-} // 關閉檢查。這會使所有錯誤回報轉向存在 IOResult 這個變數裡 | |
| 24 | + | {$I+} // 開啟回來 | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | 當關閉 IO 時他所有的輸出都會轉到 IOResult 變數裡。他是主要數字型態的變數 (cardinal type; Numbers)。所以如果你想要對它做寫入,你得使用 IntToStr 函式。不同的數字代表不同的錯誤。你可以參看這裡來了解每個不同的錯誤:[1](http://www.efg2.com/Lab/Library/Delphi/IO/IOResult.htm) | |
| 28 | + | ||
| 29 | + | ## 處理檔案的程序 | |
| 30 | + | ||
| 31 | + | 以下列出所有系統裡用來做檔案處理時會用的程序和函式。 | |
| 32 | + | ||
| 33 | + | - **Assign** - 指派名稱給檔案 | |
| 34 | + | - **Append** - 開啟已經存在的檔案,在檔案的末端接續額外內容並編輯它 | |
| 35 | + | - **BlockRead** - 對未定型態的檔案將其內容讀入到記憶體 | |
| 36 | + | - **BlockWrite** - 將記憶體中的內容寫入未定型態的檔案 | |
| 37 | + | - **Close** - 關閉開啟中的檔案 | |
| 38 | + | - **EOF** - 檢查是否為檔案末端 | |
| 39 | + | - **Erase** - 將檔案從磁碟上刪除 | |
| 40 | + | - **FilePos** - 取得檔案定位 | |
| 41 | + | - **FileSize** - 取得檔案大小 | |
| 42 | + | - **Flush** - 將檔案暫存寫入磁碟 | |
| 43 | + | - **IOResult** - 回傳最後一個檔案 IO 操作的結果 | |
| 44 | + | - **Read** - 將文字檔寫入變數 | |
| 45 | + | - **ReadLn** - 將文字檔寫入變數並換行 | |
| 46 | + | - **Reset** - 開啟一個檔案準備讀取 | |
| 47 | + | - **Rewrite** - 開啟一個檔案準備寫入 | |
| 48 | + | - **Seek** - 變更檔案中的定位 | |
| 49 | + | - **SeekEOF** - 將檔案定位指到其結尾處 | |
| 50 | + | - **SeekEOLn** - 將檔案定位指到該行結尾處 | |
| 51 | + | - **Truncate** - 於檔案定位處將內容清空 | |
| 52 | + | - **Write** - 將變數內容寫入檔案 | |
| 53 | + | - **WriteLn** - 將變數內容寫入檔案並換行 | |
| 54 | + | ||
| 55 | + | [參考單元 'System'](http://www.freepascal.org/docs-html/rtl/system/index-5.html) | |
| 56 | + | ||
| 57 | + | ## 範例 | |
| 58 | + | ||
| 59 | + | 以下為處理一型態是 TextFile 的文字檔的完整範例: | |
| 60 | + | ||
| 61 | + | ``` pascal | |
| 62 | + | program FileTest; | |
| 63 | + | ||
| 64 | + | {$mode objfpc} // 永遠都不要放記這個 | |
| 65 | + | ||
| 66 | + | uses | |
| 67 | + | Sysutils; | |
| 68 | + | ||
| 69 | + | var | |
| 70 | + | FileVar: TextFile; | |
| 71 | + | ||
| 72 | + | begin | |
| 73 | + | WriteLn('File Test'); | |
| 74 | + | AssignFile(FileVar, 'Test.txt'); // 你不一定需要 .txt,在這裡我們這麼做 | |
| 75 | + | {$I-} | |
| 76 | + | try | |
| 77 | + | Rewrite(FileVar); // 建立檔案 | |
| 78 | + | Writeln(FileVar,'Hello'); | |
| 79 | + | except | |
| 80 | + | Writeln('ERROR! IORESULT: ' + IntToStr(IOResult)); | |
| 81 | + | end; | |
| 82 | + | CloseFile(FileVar); | |
| 83 | + | ReadLn; | |
| 84 | + | end. | |
| 85 | + | ``` | |
| 86 | + | ||
| 87 | + | 現在你再用任何的文字編輯器來開啟這支文字檔,你會看到一個 Hello 寫在裡面! | |
| 88 | + | ||
| 89 | + | 在來我們接著加入內容 (編輯它) | |
| 90 | + | ||
| 91 | + | ``` pascal | |
| 92 | + | program EditFile; | |
| 93 | + | ||
| 94 | + | {$mode objfpc} | |
| 95 | + | ||
| 96 | + | uses | |
| 97 | + | Sysutils; | |
| 98 | + | ||
| 99 | + | var | |
| 100 | + | File1: TextFile; | |
| 101 | + | ||
| 102 | + | begin | |
| 103 | + | WriteLn('Append file'); | |
| 104 | + | AssignFile(File1, 'File.txt'); | |
| 105 | + | {$I-} | |
| 106 | + | try | |
| 107 | + | Append(File1, 'Some Text'); | |
| 108 | + | except | |
| 109 | + | Writeln('ERROR IORESULT:' + IntToStr(IOResult)); | |
| 110 | + | end; | |
| 111 | + | {$I+} | |
| 112 | + | CloseFile(File1); | |
| 113 | + | Readln; | |
| 114 | + | end. | |
| 115 | + | ``` | |
| 116 | + | ||
| 117 | + | 讀取檔案: | |
| 118 | + | ||
| 119 | + | ``` pascal | |
| 120 | + | program ReadFile; | |
| 121 | + | ||
| 122 | + | {$mode objfpc} | |
| 123 | + | ||
| 124 | + | uses | |
| 125 | + | Sysutils; | |
| 126 | + | ||
| 127 | + | var | |
| 128 | + | File1: TextFile; | |
| 129 | + | Str: String; | |
| 130 | + | ||
| 131 | + | begin | |
| 132 | + | Writeln('File Reading:'); | |
| 133 | + | AssignFile(File1, 'File,txt'); | |
| 134 | + | {$I-} | |
| 135 | + | try | |
| 136 | + | Reset(File1); | |
| 137 | + | repeat | |
| 138 | + | Readln(File1, Str); // 對檔案讀取整行 | |
| 139 | + | Writeln(Str); // 將讀到的一整行寫入 | |
| 140 | + | until(EOF(File1)); // EOF (檔案結尾) 迴圈會一直進行讀取直到讀不到內容為止。 | |
| 141 | + | except | |
| 142 | + | Writeln('ERROR IORESULT:', IOResult); | |
| 143 | + | end; | |
| 144 | + | {$I+} | |
| 145 | + | CloseFile(File1); | |
| 146 | + | Readln; | |
| 147 | + | end. | |
| 148 | + | ``` | |
| 149 | + | ||
| 150 | + | 在這裡的處理你也可以改用字元替代字串。這會讓它看起來很酷 :D。 | |
| 151 | + | ||
| 152 | + | # 物件導向做法 | |
| 153 | + | ||
| 154 | + | 大部份的檔案處理類別都可以直接著檔案進行讀取/存入。這些方法一般會取名為 SaveToFile 和 LoadFromFile。 | |
| 155 | + | ||
| 156 | + | ## 二進位 | |
| 157 | + | ||
| 158 | + | 若要進行直接存取可以使用 TFileStream 。這個類別將系統程序 FileOpen,FileCreate,FileRead,FileWrite,FileSeek 與 FileClose 全都包裝好放置於一起,歸屬於 FileUtil 單元。這個類型基本上算跨平台的,不過不同平台會有一些不同的實作方式。 | |
| 159 | + | ||
| 160 | + | [IO 例行程序](http://www.freepascal.org/docs-html/rtl/sysutils/ioroutines.html) | |
| 161 | + | ||
| 162 | + | ``` pascal | |
| 163 | + | var | |
| 164 | + | Buffer: array[0..10000] of Byte; | |
| 165 | + | begin | |
| 166 | + | with TFileStream.Create('SomeFile.bin', fmCreate) do | |
| 167 | + | try | |
| 168 | + | Seek('Hello'); | |
| 169 | + | Write(Buffer, SizeOf(Buffer)); | |
| 170 | + | finally | |
| 171 | + | Free; | |
| 172 | + | end; | |
| 173 | + | end; | |
| 174 | + | ``` | |
| 175 | + | ||
| 176 | + | 如果檔案比起你的系統記憶體比起來小的多,你也可以將整個檔案載入到記憶體內。 | |
| 177 | + | ||
| 178 | + | ``` pascal | |
| 179 | + | begin | |
| 180 | + | with TMemoryStream.Create do | |
| 181 | + | try | |
| 182 | + | LoadFromFile('SomeFile.bin'); | |
| 183 | + | Seek(0, soEnd); | |
| 184 | + | Write(Ord('A'), 1); | |
| 185 | + | SaveToFile('SomeFile.bin'); | |
| 186 | + | finally | |
| 187 | + | Free; | |
| 188 | + | end; | |
| 189 | + | end; | |
| 190 | + | ``` | |
| 191 | + | ||
| 192 | + | ## 文字檔案 | |
| 193 | + | ||
| 194 | + | 一般針對文字檔你可以使用 TStringList 類別來載入整支檔案到記憶體中,然後一行行來存取。 | |
| 195 | + | ||
| 196 | + | ``` pascal | |
| 197 | + | begin | |
| 198 | + | with TStringList.Create do | |
| 199 | + | try | |
| 200 | + | Add('Hello'); | |
| 201 | + | SaveToFile('SomeFile.txt'); | |
| 202 | + | finally | |
| 203 | + | Free; | |
| 204 | + | end; | |
| 205 | + | end; | |
| 206 | + | ``` | |
| 207 | + | ||
| 208 | + | --- | |
| 209 | + | *From the Free Pascal wiki, page "File Handling In Pascal/zh TW", as it stood on 2020-02-14 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
