File Handling In Pascal/zh TW

From Free Pascal wiki
Revision as of 23:48, 24 March 2012 by Vincent (talk | contribs) (Text replace - "Delphi>" to "syntaxhighlight>")
Jump to navigationJump to search

العربية (ar) English (en) español (es) suomi (fi) français (fr) 日本語 (ja) русский (ru) 中文(中国大陆)‎ (zh_CN) 中文(台灣)‎ (zh_TW)

大概所有程式設計師最需要知道的就是如何處理檔案。檔案可以用來儲存使用者的設定,錯誤報告,或更多更多。在這裡我們將教您一些最基本的文字檔案處理。

舊方法

當使用傳統非物件導向的 Pascal 時,你可以使用 TextFile 類型 (type),可以讓你建立檔案並對它寫入字串。

...
type
 TIntegerFile = file of Integer; // 可以讓你對檔案寫入整數值
 TPCharFile = file of PChar; // 將字元 (PChars) 寫入檔案 :\
 TStringFile = file of string; // 將字串寫入檔案
...

若我們僅用了 TStringFile = File,它將無法寫入任何東西!更無法將整數值寫入 TStringFile,因為它已經是字串型態的檔案。最好是使用 TextFile 的型態,它才能寫入各種不同形態的內容。

輸入輸出

IO 是 Pascal 專門用來處理檔案用的。他通常用來對付錯誤訊息。 當用來當編譯器的指令時,你可以這麼用:

{$I-} // 關閉檢查。這會使所有錯誤回報轉向存在 IOResult 這個變數裡
{$I+} // 開啟回來

當關閉 IO 時他所有的輸出都會轉到 IOResult 變數裡。他是主要數字型態的變數 (cardinal type; Numbers)。所以如果你想要對它做寫入,你得使用 IntToStr 函式。不同的數字代表不同的錯誤。你可以參看這裡來了解每個不同的錯誤:[1]

處理檔案的程序

以下列出所有系統裡用來做檔案處理時會用的程序和函式。

  • Assign - 指派名稱給檔案
  • Append - 開啟已經存在的檔案,在檔案的末端接續額外內容並編輯它
  • BlockRead - 對未定型態的檔案將其內容讀入到記憶體
  • BlockWrite - 將記憶體中的內容寫入未定型態的檔案
  • Close - 關閉開啟中的檔案
  • EOF - 檢查是否為檔案末端
  • Erase - 將檔案從磁碟上刪除
  • FilePos - 取得檔案定位
  • FileSize - 取得檔案大小
  • Flush - 將檔案暫存寫入磁碟
  • IOResult - 回傳最後一個檔案 IO 操作的結果
  • Read - 將文字檔寫入變數
  • ReadLn - 將文字檔寫入變數並換行
  • Reset - 開啟一個檔案準備讀取
  • Rewrite - 開啟一個檔案準備寫入
  • Seek - 變更檔案中的定位
  • SeekEOF - 將檔案定位指到其結尾處
  • SeekEOLn - 將檔案定位指到該行結尾處
  • Truncate - 於檔案定位處將內容清空
  • Write - 將變數內容寫入檔案
  • WriteLn - 將變數內容寫入檔案並換行


參考單元 'System'

範例

以下為處理一型態是 TextFile 的文字檔的完整範例:

program FileTest;

{$mode objfpc} // 永遠都不要放記這個

uses
 Sysutils;

var
 FileVar: TextFile;

begin
  WriteLn('File Test');
  AssignFile(FileVar, 'Test.txt'); // 你不一定需要 .txt,在這裡我們這麼做
  {$I-}
  try
    Rewrite(FileVar);  // 建立檔案
    Writeln(FileVar,'Hello');
  except
    Writeln('ERROR! IORESULT: ' + IntToStr(IOResult));
  end;
  CloseFile(FileVar);
  ReadLn;
end.

現在你再用任何的文字編輯器來開啟這支文字檔,你會看到一個 Hello 寫在裡面!

在來我們接著加入內容 (編輯它)

program EditFile;


{$mode objfpc}

uses
 Sysutils;

var
 File1: TextFile;
 
begin
  WriteLn('Append file');
  AssignFile(File1, 'File.txt');
  {$I-}
  try
    Append(File1, 'Some Text');
  except
    Writeln('ERROR IORESULT:' + IntToStr(IOResult));
  end;
  {$I+}
  CloseFile(File1);
  Readln;
end.

讀取檔案:

program ReadFile;


{$mode objfpc}

uses
 Sysutils;

var
 File1: TextFile;
 Str: String;
 
begin
  Writeln('File Reading:');
  AssignFile(File1, 'File,txt');
  {$I-}
  try
    Reset(File1);
    repeat
      Readln(File1, Str); // 對檔案讀取整行
      Writeln(Str); // 將讀到的一整行寫入
    until(EOF(File1)); // EOF (檔案結尾) 迴圈會一直進行讀取直到讀不到內容為止。
  except
    Writeln('ERROR IORESULT:', IOResult);
  end;
  {$I+}
  CloseFile(File1);
  Readln;
end.

在這裡的處理你也可以改用字元替代字串。這會讓它看起來很酷 :D。

物件導向做法

大部份的檔案處理類別都可以直接著檔案進行讀取/存入。這些方法一般會取名為 SaveToFile 和 LoadFromFile。

二進位

若要進行直接存取可以使用 TFileStream 。這個類別將系統程序 FileOpen,FileCreate,FileRead,FileWrite,FileSeek 與 FileClose 全都包裝好放置於一起,歸屬於 FileUtil 單元。這個類型基本上算跨平台的,不過不同平台會有一些不同的實作方式。

IO 例行程序

var
  Buffer: array[0..10000] of Byte;
begin
  with TFileStream.Create('SomeFile.bin', fmCreate) do 
  try
    Seek('Hello');
    Write(Buffer, SizeOf(Buffer));
  finally
    Free;
  end;
end;


如果檔案比起你的系統記憶體比起來小的多,你也可以將整個檔案載入到記憶體內。

begin
  with TMemoryStream.Create do 
  try
    LoadFromFile('SomeFile.bin');
    Seek(0, soEnd);
    Write(Ord('A'), 1);
    SaveToFile('SomeFile.bin');
  finally
    Free;
  end;
end;


文字檔案

一般針對文字檔你可以使用 TStringList 類別來載入整支檔案到記憶體中,然後一行行來存取。

begin
  with TStringList.Create do 
  try
    Add('Hello');
    SaveToFile('SomeFile.txt');
  finally
    Free;
  end;
end;