procedure TForm1.Button1Click(Sender: TObject);
var iFileHandle: Integer; iFileLength: Integer; iBytesRead: Integer; Buffer: PChar; i: Integer begin if OpenDialog1.Execute then begin try iFileHandle := FileOpen(OpenDialog1.FileName, fmOpenRead); iFileLength := FileSeek(iFileHandle,0,2); FileSeek(iFileHandle,0,0); Buffer := PChar(AllocMem(iFileLength + 1)); iBytesRead = FileRead(iFileHandle, Buffer, iFileLength); FileClose(iFileHandle);
for i := 0 to iBytesRead-1 do begin StringGrid1.RowCount := StringGrid1.RowCount + 1; StringGrid1.Cells[1,i+1] := Buffer[i]; StringGrid1.Cells[2,i+1] := IntToStr(Integer(Buffer[i])); end; finally FreeMem(Buffer); end; end; end;
Delphi同Object Pascal一樣支持三種文件類型,,即:文本文件、記錄文件,、無類型文件,。
6.1.1文本文件
文本文件類型的變量用如下方法聲明:
var TextFileVar: Text ;
文本文件是以行為單位進(jìn)行讀、寫操作的。由于每一行長度不一定相同,,不能計算出給定行在文件中的確切位置,,因而只能順序地讀寫。而且文本文件只能單獨為讀或?qū)懚蜷_,,在一個打開的文本文件上同時進(jìn)行讀,、寫操作是不允許的。
6.1.1.1文本文件的打開,、關(guān)閉
文本文件的打開需要兩個步驟:(1). 文件變量與文件名關(guān)聯(lián),;(2). 初始化讀寫。 關(guān)聯(lián)文件變量與文件名調(diào)用AssignFile標(biāo)準(zhǔn)過程:
AssignFile ( TextFileVar , FileName ) ;
FileName 既可以是全路徑名,,也可以僅是文件名,。對于后者系統(tǒng)將在當(dāng)前目錄下查找。 AssignFile是Delphi新提供的一個函數(shù),,其功能等價于Object Pascal中的Assign,。而Assign在Delphi中更多地被用作一個方法名。 初始化讀寫有三種方式: 1. Reset : 為讀打開文件并把文件指針移動到文件首,; 2. Rewrite : 為寫創(chuàng)建一個新文件; 3. Append : 為寫打開存在的文件并把文件指針定位在文件尾,。 當(dāng)使用Reset或Append過程而文件不存在時將會引發(fā)一個I/O異常,。有關(guān)I/O異常的處理請參看本章例程和第十二章中的介紹。 文件的關(guān)閉很簡單,,只須調(diào)用CloseFile過程即可,。 雖然Delphi應(yīng)用程序在退出時會自動關(guān)閉所有打開的文件,但自己動手關(guān)閉文件可以確保釋放文件句柄,,并使程序的可移植性增強,。 為保持兼容,Delphi也允許用戶用Assign建立關(guān)聯(lián),,Close關(guān)閉文件,。
6.1.1.2文本文件的讀寫
從文本文件中讀取信息用Read、Readln兩個標(biāo)準(zhǔn)過程,。 當(dāng)讀入數(shù)值時,,Read、Readln假定數(shù)值是用一個或多個空格分開的,,而不是逗號,、分號或其它字符。對如下一條語句:
Read ( TextFileVar , Num1 , Num2 , Num3 ) ;
如果文件中的數(shù)值是: 100200300 則能夠成功讀入,,而若文件中的數(shù)值是 100200,,300 則Read讀入“200,”并試圖把它轉(zhuǎn)化成一個數(shù)值時會引發(fā)一個異常,。 當(dāng)讀入字符是字符串時,,Read,、Readln過程總是讀取盡可能多的字符填充到字符串變量中或一直讀到行結(jié)束符為止。因此從文本文件中讀取格式化的字符串?dāng)?shù)據(jù),,必須聲明與其長度相匹配的字符串變量,。如果要從文件中讀取單詞,必須先把文件中的每一行讀入字符串,,然后再從字符串中逐個分析出單詞,。或者一次只從文本文件中讀入一個字符并測試每個字符后是否是單詞斷開處,。 格式化字符串之間的分隔符應(yīng)讀入到一個臨時變量中,,而字符串與數(shù)值、數(shù)值與數(shù)值間的分隔符讀入時會自動識別剔除,。對如下一行數(shù)據(jù): Mon12:1040 50 定義
var Day: string[3] ; Time: string[5] ; Num1, Num2: Integer ;
則須用如下的read 語句讀入:
read ( TextFileVar , Day , c , Time , Num1 , Num2 ) ;
C為一個臨時字符變量,。
6.1.1.3文本文件的編輯
在Delphi中實現(xiàn)對一個文本文件的編輯,只須讓其與一個Tmemo控件建立關(guān)聯(lián)即可:
Memo1.Lines.LoadFromFile ( TextFileName ) ;
這樣在TMemo上所做的一切修改當(dāng)調(diào)用Memo部件的SaveToFile方法后都會反映到文件中去,。
6.1.2 記錄文件
記錄文件是一種操作更為靈活的文件類型,。它允許同時為讀和寫打開,而且由于記錄文件中每條記錄的長度固定,,所以可隨機存取,。 記錄文件的類型變量可如下聲明:
var RecordFileVar: file of RecordType;
RecordType是一個自定義的記錄類型。 有關(guān)記錄文件的操作我們將在下一節(jié)中結(jié)合例程進(jìn)行討論,。
6.1.3 無類型文件
無類型文件提供了底層的I/O通道,,可用于存取可變長度記錄的文件。經(jīng)常用于文件的復(fù)制操作中,。由于Delphi提供了更好的方法(見第四節(jié)),,所以無類型文件很少使用。有興趣的讀者可參看BlockRead,、BlockWrite兩個聯(lián)機幫助主題,。
6.1.4 Delphi的文件管理標(biāo)準(zhǔn)過程
根據(jù)功能我們把標(biāo)準(zhǔn)過程劃分為十一類進(jìn)行介紹。
6.1.4.1 文件的打開與關(guān)閉
AssignFile :把一個外部文件名和一個文件變量相關(guān)聯(lián) Reset :打開一個存在的文件 Rewrite :創(chuàng)建并打開一個新文件(或覆蓋原有文件) Append :以添加方式打開一個文件(只適用于文本文件) CloseFile :關(guān)閉一個打開的文件 FileOpen :打開一個特定的文件并返回文件句柄 FileCreate :創(chuàng)建一個給定文件名的文件并返回文件句柄 FileClose :關(guān)閉一個特定句柄的文件
后邊三個文件主要供系統(tǒng)內(nèi)部使用,,在文件復(fù)制的編程中也往往會用到,。它們操作的對象是文件句柄而不是文件變量。
6.1.4.2 文件定位
Seek:把文件當(dāng)前位置移到指定部分 FilePos:返回文件的當(dāng)前位置 Eoln:返回行結(jié)束標(biāo)志 EOF:返回文件結(jié)束標(biāo)志 FileSeek: 改變當(dāng)前文件指針的位置
Seek與FileSeek的區(qū)別是:1. Seek僅用于記錄文件,;2. FileSeek的參數(shù)是文件句柄,、偏移量、起始位置,。其中起始位置有文件首,、當(dāng)前位置、文件尾三種選擇。Seek的參數(shù)是文件變量,、偏移量,,偏移量是從文件首開始定位的。3. FileSeek的偏移量以字節(jié)數(shù)來計算,,而Seek是根據(jù)記錄號進(jìn)行移動,。 Seek、FilePos僅用于記錄文件,。但任何文件都可以看作是基于字節(jié)的記錄文件,。下面一段程序表示了它們的用法。
{ 該例子的設(shè)計界面為一個包含TOpenDialog部件的窗體,。}
uses Dialogs; var f: file of Byte; size: Longint; S: String; y: Integer; begin if OpenDialog1.Execute then begin AssignFile(f, OpenDialog1.FileName); Reset(f); size := FileSize(f); S := ‘File size in bytes: ‘ + IntToStr(size); y := 10; Canvas.TextOut(5, y, S); y := y + Canvas.TextHeight(S) + 5; S := ‘Seeking halfway into file...‘; Canvas.TextOut(5, y, S); y := y + Canvas.TextHeight(S) + 5; Seek(f,size div 2); S := ‘Position is now ‘ + IntToStr(FilePos(f)); Canvas.TextOut(5, y, S); CloseFile(f); end; end.
6.1.4.3 文件刪除與截斷
Erase:刪除一個存在的文件 DeleteFile:刪除一個文件 Truncate:從文件當(dāng)前位置將文件截斷
Erase與DeleteFile的區(qū)別是:Erase以文件變量為參數(shù),,當(dāng)文件不能刪除時引起一個異常;DeleteFile以文件名為參數(shù),,當(dāng)文件不存在或不能刪除時返回False,,而并不引起一個異常。
6.1.4.4 文件名操作
Rename:文件更名,,以文件變量為操作對象 RenameFile:文件更名,,參數(shù)為文件的原名和新名 ChangeFileExt :改變文件擴展名 ExpandFileName:返回文件全路徑名 ExtractFileExt :返回文件擴展名 ExtractFileName:從全路徑名中返回文件名 ExtractFilePath:返回特定文件的路徑
6.1.4.5 文件屬性
FileGetAttr:返回文件屬性 FileSetAttr:設(shè)置文件屬性
6.1.4.6 文件狀態(tài)
FileSize:返回文件對象大小 IOResult:返回上一次I/O操作的狀態(tài) FileExists :檢測文件是否存在
6.1.4.7 文件日期
DateTimeToFileDate:把Delphi日期格式轉(zhuǎn)換為DOS日期格式 FileDateToDateTime:把DOS日期格式轉(zhuǎn)換為Delphi日期格式 FileGetDate:返回文件的DOS日期時間戳 FileSetDate:設(shè)置文件的DOS日期時間戳
6.1.4.8 文件讀寫
Read,Readln:從文本或記錄文件中讀取變量 Write:將指定變量寫入文本或記錄文件 Writeln:將指定變量寫入文本文件并寫入一個行結(jié)束標(biāo)志 FileRead:從一個指定文件中讀取變量 FileWrite :向指定文件寫入數(shù)據(jù)
FileRead和FileWrite都是以文件句柄為操作對象,,主要供系統(tǒng)內(nèi)部使用,。
6.1.4.9 目錄操作
MkDir:創(chuàng)建當(dāng)前目錄的子目錄 ChDir:改變當(dāng)前目錄 GetDir:返回特定磁盤的當(dāng)前目錄 RmDir:刪除一個空子目錄
6.1.4.10 磁盤操作
DiskFree:返回磁盤自由空間 DiskSize:返回特定磁盤的大小
6.1.4.11 文件查找
FileSearch:查找目錄中是否存在某一特定文件 FindFirst :在目錄中查找與給定文件名(可以包含匹配符)及屬性集相匹配的第一個文件 FindNext:返回符合條件的下一個文件 FindClose :中止一個FindFirst / FindNext序列
有關(guān)文件管理標(biāo)準(zhǔn)過程/函數(shù)的更詳細(xì)資料,請查閱Delphi相關(guān)的Help主題,。以上的大部分過程在后面都有應(yīng)用實例,讀者可以從中體會其用法,。 在Delphi的聯(lián)機幫助Help系統(tǒng)中把有關(guān)文件的過程/函數(shù)分為兩個主題:I/O Routine和File _Management Routine,。前者大部分以文件變量為操作對象,而后者大部分以文件名或文件句柄為操作對象,。這里為了方便讀者的使用,,我們按功能重新進(jìn)行了分類。在下一節(jié)中主要應(yīng)用I/O Routine主題下的過程,,而在第四節(jié)的綜合舉例中主要應(yīng)用File_Management Routine主題下的過程,。 另外,Windows提供了許多有關(guān)文件管理的API函數(shù),。雖然在一般情況下,,利用Delphi提供的函數(shù)已足夠解決問題,但有時候仍然需要使用Windows API,。在(6.4.4.2)中我們就用到了Windows API函數(shù)GetDriveType,。有關(guān)Windows API函數(shù)的情況,請讀者參閱相關(guān)的資料,這里不再進(jìn)行介紹,。
|