文件是同一類型元素的有序集合,是內(nèi)存與外設間傳輸數(shù)據(jù)的渠道。一些外設如顯示器、鍵盤、打印機等都可以看作文件,但最常用的還是磁盤文件,這也是我們主要討論的對象。
Delphi繼承了ObjectPascal的文件管理功能,并有很大的發(fā)展,其中最主要的是提供了用于文件管理的標準控件,同時也提供了更多的文件管理函數(shù)。利用Delphi的強大功能,開發(fā)一個自己的文件管理系統(tǒng)就成為很容易的事。
首先介紹Delphi文件管理的基本概念和標準過程/函數(shù),并提供了一個記錄文件的應用實例,這是從我們實際課題開發(fā)中提取出來的。而后介紹Delphi提供的文件控件的使用方法。最后提供的一個綜合例程MDI文件管理器則是對Delphi文件管理功能的綜合應用。
1文件類型和標準過程
Delphi同ObjectPascal一樣支持三種文件類型,即: 文本文件、記錄文件、無類型文件 。
1.1文本文件
文本文件類型的變量用如下方法聲明:
var
TextFileVar:Text;
文本文件是以行為單位進行讀、寫操作的。由于每一行長度不一定相同,不能計算出給定行在文件中的確切位置,因而只能順序地讀寫。而且文本文件只能單獨為讀或?qū)懚蜷_, 在一個打開的文本文件上同時進行讀、寫操作是不允許的 。
1.1.1文本文件的打開、關(guān)閉
文本文件的打開需要兩個步驟:(1).文件變量與文件名關(guān)聯(lián);(2).初始化讀寫。
聯(lián)文件變量與文件名調(diào)用AssignFile標準過程:
AssignFile(TextFileVar,FileName);
FileName既可以是全路徑名,也可以僅是文件名。對于后者系統(tǒng)將在當前目錄下查找。
AssignFile是Delphi新提供的一個函數(shù),其功能等價于ObjectPascal中的Assign。而Assign在Delphi中更多地被用作一個方法名。
初始化讀寫有三種方式:
1.Reset:為讀打開文件并把文件指針移動到文件首;
2.Rewrite:為寫創(chuàng)建一個新文件;
3.Append:為寫打開存在的文件并把文件指針定位在文件尾。
當使用Reset或Append過程而文件不存在時將會引發(fā)一個I/O異常。
文件的關(guān)閉很簡單,只須調(diào)用CloseFile過程即可。
雖然Delphi應用程序在退出時會自動關(guān)閉所有打開的文件,但自己動手關(guān)閉文件可以確保釋放文件句柄,并使程序的可移植性增強。
為保持兼容,Delphi也允許用戶用Assign建立關(guān)聯(lián),Close關(guān)閉文件。
1.1.2文本文件的讀寫
從文本文件中讀取信息用Read、Readln兩個標準過程。
當讀入數(shù)值時,Read、Readln假定數(shù)值是用一個或多個空格分開的,而不是逗號、分號或其它字符。對如下一條語句:
Read(TextFileVar,Num1,Num2,Num3);
如果文件中的數(shù)值是:
100200300
則能夠成功讀入,而若文件中的數(shù)值是
100200,300
則Read讀入“200,”并試圖把它轉(zhuǎn)化成一個數(shù)值時會引發(fā)一個異常。
當讀入字符是字符串時,Read、Readln過程總是讀取盡可能多的字符填充到字符串變量中或一直讀到行結(jié)束符為止。 因此從文本文件中讀取格式化的字符串數(shù)據(jù),必須聲明與其長度相匹配的字符串變量 。如果要從文件中讀取單詞,必須先把文件中的每一行讀入字符串,然后再從字符串中逐個分析出單詞。或者一次只從文本文件中讀入一個字符并測試每個字符后是否是單詞斷開處。
格式化字符串之間的分隔符應讀入到一個臨時變量中,而字符串與數(shù)值、數(shù)值與數(shù)值間的分隔符讀入時會自動識別剔除。對如下一行數(shù)據(jù):
Mon12:104050
定義
var
Day:string[3];
Time:string[5];
Num1,Num2:Integer;
則須用如下的read語句讀入:
read(TextFileVar,Day,c,Time,Num1,Num2);
C為一個臨時字符變量。
1.1.3文本文件的編輯
在Delphi中實現(xiàn)對一個文本文件的編輯,只須讓其與一個Tmemo控件建立關(guān)聯(lián)即可:
Memo1.Lines.LoadFromFile(TextFileName);
這樣在TMemo上所做的一切修改當調(diào)用Memo部件的SaveToFile方法后都會反映到文件中去。
1.2記錄文件
記錄文件是一種操作更為靈活的文件類型。它允許同時為讀和寫打開,而且由于記錄文件中每條記錄的長度固定,所以可隨機存取。
記錄文件的類型變量可如下聲明:
var
RecordFileVar:fileofRecordType;
RecordType是一個自定義的記錄類型。
1.3無類型文件
無類型文件提供了底層的I/O通道,可用于存取可變長度記錄的文件。經(jīng)常用于文件的復制操作中。由于Delphi提供了更好的方法,所以無類型文件很少使用。有興趣的讀者可參看BlockRead、BlockWrite兩個聯(lián)機幫助主題。
1.4Delphi的文件管理標準過程
根據(jù)功能我們把標準過程劃分為十一類進行介紹。
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)部使用,在文件復制的編程中也往往會用到。它們操作的對象是文件句柄而不是文件變量。
1.4.2文件定位
Seek:把文件當前位置移到指定部分
FilePos:返回文件的當前位置
Eoln:返回行結(jié)束標志
EOF:返回文件結(jié)束標志
FileSeek:改變當前文件指針的位置
Seek與FileSeek的區(qū)別是:
1 .Seek僅用于記錄文件;
2 .FileSeek的參數(shù)是文件句柄、偏移量、起始位置。其中起始位置有文件首、當前位置、文件尾三種選擇。Seek的參數(shù)是文件變量、偏移量,偏移量是從文件首開始定位的。
3 .FileSeek的偏移量以字節(jié)數(shù)來計算,而Seek是根據(jù)記錄號進行移動。
Seek、FilePos僅用于記錄文件。但任何文件都可以看作是基于字節(jié)的記錄文件。下面一段程序表示了它們的用法。
{該例子的設計界面為一個包含TOpenDialog部件的窗體。}
1.4.3文件刪除與截斷
Erase:刪除一個存在的文件
DeleteFile:刪除一個文件
Truncate:從文件當前位置將文件截斷
Erase與DeleteFile的區(qū)別是:Erase以文件變量為參數(shù),當文件不能刪除時引起一個異常;DeleteFile以文件名為參數(shù),當文件不存在或不能刪除時返回False,而并不引起一個異常。
1.4.4文件名操作
Rename:文件更名,以文件變量為操作對象
RenameFile:文件更名,參數(shù)為文件的原名和新名
ChangeFileExt:改變文件擴展名
ExpandFileName:返回文件全路徑名
ExtractFileExt:返回文件擴展名
ExtractFileName:從全路徑名中返回文件名
ExtractFilePath:返回特定文件的路徑
1.4.5文件屬性
FileGetAttr:返回文件屬性
FileSetAttr:設置文件屬性
1.4.6文件狀態(tài)
FileSize:返回文件對象大小
IOResult:返回上一次I/O操作的狀態(tài)
FileExists:檢測文件是否存在
1.4.7文件日期
DateTimeToFileDate:把Delphi日期格式轉(zhuǎn)換為DOS日期格式
FileDateToDateTime:把DOS日期格式轉(zhuǎn)換為Delphi日期格式
FileGetDate:返回文件的DOS日期時間戳
FileSetDate:設置文件的DOS日期時間戳
1.4.8文件讀寫
Read,Readln:從文本或記錄文件中讀取變量
Write:將指定變量寫入文本或記錄文件
Writeln:將指定變量寫入文本文件并寫入一個行結(jié)束標志
FileRead:從一個指定文件中讀取變量
FileWrite:向指定文件寫入數(shù)據(jù)
FileRead和FileWrite都是以文件句柄為操作對象,主要供系統(tǒng)內(nèi)部使用。
1.4.9目錄操作
MkDir:創(chuàng)建當前目錄的子目錄
ChDir:改變當前目錄
GetDir:返回特定磁盤的當前目錄
RmDir:刪除一個空子目錄
1.4.10磁盤操作
DiskFree:返回磁盤自由空間
DiskSize:返回特定磁盤的大小
1.4.11文件查找
FileSearch:查找目錄中是否存在某一特定文件
FindFirst:在目錄中查找與給定文件名(可以包含匹配符)及屬性集相匹配的第一個文件
FindNext:返回符合條件的下一個文件
FindClose:中止一個FindFirst/FindNext序列
有關(guān)文件管理標準過程/函數(shù)的更詳細資料,請查閱Delphi相關(guān)的Help主題。以上的大部分過程在后面都有應用實例,可以從中體會其用法。
在Delphi的聯(lián)機幫助Help系統(tǒng)中把有關(guān)文件的過程/函數(shù)分為兩個主題:I/ORoutine和File_ManagementRoutine。前者大部分以文件變量為操作對象,而后者大部分以文件名或文件句柄為操作對象。這里為了方便使用,我們按功能重新進行了分類。在下一節(jié)中主要應用I/ORoutine主題下的過程,而在第四節(jié)的綜合舉例中主要應用File_ManagementRoutine主題下的過程。
另外,Windows提供了許多有關(guān)文件管理的API函數(shù)。雖然在一般情況下,利用Delphi提供的函數(shù)已足夠解決問題,但有時候仍然需要使用WindowsAPI。有關(guān)WindowsAPI函數(shù)的情況,這里不再進行介紹。
Delphi繼承了ObjectPascal的文件管理功能,并有很大的發(fā)展,其中最主要的是提供了用于文件管理的標準控件,同時也提供了更多的文件管理函數(shù)。利用Delphi的強大功能,開發(fā)一個自己的文件管理系統(tǒng)就成為很容易的事。
首先介紹Delphi文件管理的基本概念和標準過程/函數(shù),并提供了一個記錄文件的應用實例,這是從我們實際課題開發(fā)中提取出來的。而后介紹Delphi提供的文件控件的使用方法。最后提供的一個綜合例程MDI文件管理器則是對Delphi文件管理功能的綜合應用。
1文件類型和標準過程
Delphi同ObjectPascal一樣支持三種文件類型,即: 文本文件、記錄文件、無類型文件 。
1.1文本文件
文本文件類型的變量用如下方法聲明:
var
TextFileVar:Text;
文本文件是以行為單位進行讀、寫操作的。由于每一行長度不一定相同,不能計算出給定行在文件中的確切位置,因而只能順序地讀寫。而且文本文件只能單獨為讀或?qū)懚蜷_, 在一個打開的文本文件上同時進行讀、寫操作是不允許的 。
1.1.1文本文件的打開、關(guān)閉
文本文件的打開需要兩個步驟:(1).文件變量與文件名關(guān)聯(lián);(2).初始化讀寫。
聯(lián)文件變量與文件名調(diào)用AssignFile標準過程:
AssignFile(TextFileVar,FileName);
FileName既可以是全路徑名,也可以僅是文件名。對于后者系統(tǒng)將在當前目錄下查找。
AssignFile是Delphi新提供的一個函數(shù),其功能等價于ObjectPascal中的Assign。而Assign在Delphi中更多地被用作一個方法名。
初始化讀寫有三種方式:
1.Reset:為讀打開文件并把文件指針移動到文件首;
2.Rewrite:為寫創(chuàng)建一個新文件;
3.Append:為寫打開存在的文件并把文件指針定位在文件尾。
當使用Reset或Append過程而文件不存在時將會引發(fā)一個I/O異常。
文件的關(guān)閉很簡單,只須調(diào)用CloseFile過程即可。
雖然Delphi應用程序在退出時會自動關(guān)閉所有打開的文件,但自己動手關(guān)閉文件可以確保釋放文件句柄,并使程序的可移植性增強。
為保持兼容,Delphi也允許用戶用Assign建立關(guān)聯(lián),Close關(guān)閉文件。
1.1.2文本文件的讀寫
從文本文件中讀取信息用Read、Readln兩個標準過程。
當讀入數(shù)值時,Read、Readln假定數(shù)值是用一個或多個空格分開的,而不是逗號、分號或其它字符。對如下一條語句:
Read(TextFileVar,Num1,Num2,Num3);
如果文件中的數(shù)值是:
100200300
則能夠成功讀入,而若文件中的數(shù)值是
100200,300
則Read讀入“200,”并試圖把它轉(zhuǎn)化成一個數(shù)值時會引發(fā)一個異常。
當讀入字符是字符串時,Read、Readln過程總是讀取盡可能多的字符填充到字符串變量中或一直讀到行結(jié)束符為止。 因此從文本文件中讀取格式化的字符串數(shù)據(jù),必須聲明與其長度相匹配的字符串變量 。如果要從文件中讀取單詞,必須先把文件中的每一行讀入字符串,然后再從字符串中逐個分析出單詞。或者一次只從文本文件中讀入一個字符并測試每個字符后是否是單詞斷開處。
格式化字符串之間的分隔符應讀入到一個臨時變量中,而字符串與數(shù)值、數(shù)值與數(shù)值間的分隔符讀入時會自動識別剔除。對如下一行數(shù)據(jù):
Mon12:104050
定義
var
Day:string[3];
Time:string[5];
Num1,Num2:Integer;
則須用如下的read語句讀入:
read(TextFileVar,Day,c,Time,Num1,Num2);
C為一個臨時字符變量。
1.1.3文本文件的編輯
在Delphi中實現(xiàn)對一個文本文件的編輯,只須讓其與一個Tmemo控件建立關(guān)聯(lián)即可:
Memo1.Lines.LoadFromFile(TextFileName);
這樣在TMemo上所做的一切修改當調(diào)用Memo部件的SaveToFile方法后都會反映到文件中去。
1.2記錄文件
記錄文件是一種操作更為靈活的文件類型。它允許同時為讀和寫打開,而且由于記錄文件中每條記錄的長度固定,所以可隨機存取。
記錄文件的類型變量可如下聲明:
var
RecordFileVar:fileofRecordType;
RecordType是一個自定義的記錄類型。
1.3無類型文件
無類型文件提供了底層的I/O通道,可用于存取可變長度記錄的文件。經(jīng)常用于文件的復制操作中。由于Delphi提供了更好的方法,所以無類型文件很少使用。有興趣的讀者可參看BlockRead、BlockWrite兩個聯(lián)機幫助主題。
1.4Delphi的文件管理標準過程
根據(jù)功能我們把標準過程劃分為十一類進行介紹。
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)部使用,在文件復制的編程中也往往會用到。它們操作的對象是文件句柄而不是文件變量。
1.4.2文件定位
Seek:把文件當前位置移到指定部分
FilePos:返回文件的當前位置
Eoln:返回行結(jié)束標志
EOF:返回文件結(jié)束標志
FileSeek:改變當前文件指針的位置
Seek與FileSeek的區(qū)別是:
1 .Seek僅用于記錄文件;
2 .FileSeek的參數(shù)是文件句柄、偏移量、起始位置。其中起始位置有文件首、當前位置、文件尾三種選擇。Seek的參數(shù)是文件變量、偏移量,偏移量是從文件首開始定位的。
3 .FileSeek的偏移量以字節(jié)數(shù)來計算,而Seek是根據(jù)記錄號進行移動。
Seek、FilePos僅用于記錄文件。但任何文件都可以看作是基于字節(jié)的記錄文件。下面一段程序表示了它們的用法。
{該例子的設計界面為一個包含TOpenDialog部件的窗體。}
程序代碼
usesDialogs;
var
f:fileofByte;
size:Longint;
S:String;
y:Integer;
begin
ifOpenDialog1.Executethen
begin
AssignFile(f,OpenDialog1.FileName);
Reset(f);
size:=FileSize(f);
S:='Filesizeinbytes:'+IntToStr(size);
y:=10;
Canvas.TextOut(5,y,S);
y:=y+Canvas.TextHeight(S)+5;
S:='Seekinghalfwayintofile...';
Canvas.TextOut(5,y,S);
y:=y+Canvas.TextHeight(S)+5;
Seek(f,sizediv2);
S:='Positionisnow'+IntToStr(FilePos(f));
Canvas.TextOut(5,y,S);
CloseFile(f);
end;
end.
var
f:fileofByte;
size:Longint;
S:String;
y:Integer;
begin
ifOpenDialog1.Executethen
begin
AssignFile(f,OpenDialog1.FileName);
Reset(f);
size:=FileSize(f);
S:='Filesizeinbytes:'+IntToStr(size);
y:=10;
Canvas.TextOut(5,y,S);
y:=y+Canvas.TextHeight(S)+5;
S:='Seekinghalfwayintofile...';
Canvas.TextOut(5,y,S);
y:=y+Canvas.TextHeight(S)+5;
Seek(f,sizediv2);
S:='Positionisnow'+IntToStr(FilePos(f));
Canvas.TextOut(5,y,S);
CloseFile(f);
end;
end.
1.4.3文件刪除與截斷
Erase:刪除一個存在的文件
DeleteFile:刪除一個文件
Truncate:從文件當前位置將文件截斷
Erase與DeleteFile的區(qū)別是:Erase以文件變量為參數(shù),當文件不能刪除時引起一個異常;DeleteFile以文件名為參數(shù),當文件不存在或不能刪除時返回False,而并不引起一個異常。
1.4.4文件名操作
Rename:文件更名,以文件變量為操作對象
RenameFile:文件更名,參數(shù)為文件的原名和新名
ChangeFileExt:改變文件擴展名
ExpandFileName:返回文件全路徑名
ExtractFileExt:返回文件擴展名
ExtractFileName:從全路徑名中返回文件名
ExtractFilePath:返回特定文件的路徑
1.4.5文件屬性
FileGetAttr:返回文件屬性
FileSetAttr:設置文件屬性
1.4.6文件狀態(tài)
FileSize:返回文件對象大小
IOResult:返回上一次I/O操作的狀態(tài)
FileExists:檢測文件是否存在
1.4.7文件日期
DateTimeToFileDate:把Delphi日期格式轉(zhuǎn)換為DOS日期格式
FileDateToDateTime:把DOS日期格式轉(zhuǎn)換為Delphi日期格式
FileGetDate:返回文件的DOS日期時間戳
FileSetDate:設置文件的DOS日期時間戳
1.4.8文件讀寫
Read,Readln:從文本或記錄文件中讀取變量
Write:將指定變量寫入文本或記錄文件
Writeln:將指定變量寫入文本文件并寫入一個行結(jié)束標志
FileRead:從一個指定文件中讀取變量
FileWrite:向指定文件寫入數(shù)據(jù)
FileRead和FileWrite都是以文件句柄為操作對象,主要供系統(tǒng)內(nèi)部使用。
1.4.9目錄操作
MkDir:創(chuàng)建當前目錄的子目錄
ChDir:改變當前目錄
GetDir:返回特定磁盤的當前目錄
RmDir:刪除一個空子目錄
1.4.10磁盤操作
DiskFree:返回磁盤自由空間
DiskSize:返回特定磁盤的大小
1.4.11文件查找
FileSearch:查找目錄中是否存在某一特定文件
FindFirst:在目錄中查找與給定文件名(可以包含匹配符)及屬性集相匹配的第一個文件
FindNext:返回符合條件的下一個文件
FindClose:中止一個FindFirst/FindNext序列
有關(guān)文件管理標準過程/函數(shù)的更詳細資料,請查閱Delphi相關(guān)的Help主題。以上的大部分過程在后面都有應用實例,可以從中體會其用法。
在Delphi的聯(lián)機幫助Help系統(tǒng)中把有關(guān)文件的過程/函數(shù)分為兩個主題:I/ORoutine和File_ManagementRoutine。前者大部分以文件變量為操作對象,而后者大部分以文件名或文件句柄為操作對象。這里為了方便使用,我們按功能重新進行了分類。在下一節(jié)中主要應用I/ORoutine主題下的過程,而在第四節(jié)的綜合舉例中主要應用File_ManagementRoutine主題下的過程。
另外,Windows提供了許多有關(guān)文件管理的API函數(shù)。雖然在一般情況下,利用Delphi提供的函數(shù)已足夠解決問題,但有時候仍然需要使用WindowsAPI。有關(guān)WindowsAPI函數(shù)的情況,這里不再進行介紹。
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
