程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi文件管理(3)

Delphi文件管理(3)

編輯:Delphi

這種思想的核心是創建一個新文件保存更新後的內容。若新文件順利創建,則刪除原文件,否則恢復原來的文件。程序清單如下: 

  procedure TRecFileForm.DeleteButtonClick(Sender: TObject);
var
NewFile: MethodFileType;
MethodRec: TMethod;
NewFileName: String;
i: Integer;
begin
if FileOpened = False then Exit;
CurrentRec := StringGrid1.Row-1;
if CurrentRec < 0 then Exit;
if MessageDlg('Delete Current Record ?', mtConfirmation,
[mbYes, mbNo], 0) = idYes then
begin
HazAttr.text := '';
NewFileName := ChangeFileExt(FileName,'.sav');
try
AssignFile(NewFile,FileName);
ReWrite(NewFile);
Except
On EInOutError do
begin
Rename(MethodFile,FileName);
Exit;
end;
end;
for i := 1 to Count do
if I <> CurrentRec+1 then
begin
MethodRec := GridToRec(i);
Write(NewFile,MethodRec);
end;
closeFile(MethodFile);
try
AssignFile(MethodFile,Filename);
Reset(MethodFile);
except
on EInOutError do
begin
DeleteFile(FileName);
AssignFile(MethodFile,NewFileName);
Reset(MethodFile);
Rename(MethodFile,FileName);
Exit;
end;
DeleteFile(NewFileName);
Count:=Count-1;
ChangeGrid;
end;
end;

  對於記錄插入,方法基本同上。對於排序,可先將關鍵域讀入排序,而後再按排序結果對應的記錄號順序重寫文件。 

 6.2.8 結果綜合 

  對不同方法的評估結果,可按一定的公式進行綜合。當用戶按下“計算”按鈕時,系統進行計算並把綜合結果寫入HazAttr只讀編輯框中。

  為保證結果顯示的正確性,每次增加、修改、刪除操作確認後HazAttr編輯框清空。 

  6.2.9 編輯對話框的輸入檢查 

  當用戶單擊“增加”或“修改”按鈕時系統將彈出一個編輯對話框,讓用戶輸入或修改記錄內容。其中的三個編輯框,一個組合列表框分別對應TMethod 的四個域。由於TMethod的Result域必須是[0,1]間的小數,因此當用戶按OK鍵關閉對話框時應進行類型和范圍檢查。

  在VB中我做過同樣的工作,那時需要對用戶輸入的鍵碼逐個進行判斷。但這種方法很繁瑣、很難做圓滿(如不能很好地支持編輯鍵)。而Object Pascal提供了更好的方法。這種方法的關鍵就在於它的類型轉換函數Val: 

  procedure Val(Str: String;var V; var Code: Integer); 

  V是由Str轉換成的整型或實型數。若字符串非法,則出錯位置返至Code;否則置Code為0。字符串非法並不會引發一個轉換異常。

  如果轉換後的數超出了我們的范圍,則顯式把Code置為-1。最後統一通過檢測Code是否為0來判斷輸入是否合法。

  我們把輸入檢查放在對話框的OnCloseQuery事件處理過程中。如輸入非法,則禁止對話框關閉,並將輸入焦點置於Result編輯框中。但假如用戶按了Cancel按鈕,則這種檢查是多余的。為此定義一個布爾變量IsCancel,對話框生成時置為False。假如用戶按下Cancel,則置為True,此時OnCloseQuery事件不進行輸入檢查。

  對話框的OnCloseQuery事件處理過程的程序清單如下: 

  procedure TEditForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
Res: Real;
k: Integer;
begin
if IsCancel = False then
begin
val(Result.text,Res,k);
if (Res > 1) or (Res < 0) then k := -1;
if k <> 0 then
begin
MessageDlg('非法輸入 !',mtWarning,[mbOK],0);
Result.text := '';
CanClose := False;
Result.SetFocus;
end;
end;
end;
 

 6.2.10 文件和系統的關閉 

  文件關閉須調用CloseFile過程: 

  CloseFile(MethodFile); 

  並對系統的狀態重新進行設置。

  系統關閉時首先檢測當前是否有打開的文件。若有則先關閉文件。這在主窗口的OnCloseQuery事件中實現。

  實現文件關閉的程序清單如下: 

  procedure TRecFileForm.CloseButtonClick(Sender: TObject);
begin
if FileOpened then
begin
CloseFile(MethodFile);
FileOpened := False;
ClearGrid;
OpenButton.Enabled := True;
NewButton.Enabled := True;
CloseButton.Enabled := False;
RecFileForm.Caption := FormCaption;
end;
end;
 

  實現系統關閉前檢查的程序清單如下:

  procedure TRecFileForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
if FileOpened then
closeFile(MethodFile);
end;
 

  6.2.11 記錄文件小結 

  我們所舉的例子雖然簡單,但基本覆蓋了記錄文件操作的主要方面。這裡關鍵問題在於靈活應用Delphi提供的文件管理函數。同時,為了保證程序的健壯性應對異常進行捕獲並處理。在數據庫應用技術發展的今天,記錄文件的重要性也許有所下降,但對象我們這裡所處理的簡單問題它仍有用武之地。

  這裡所舉的例子一次只能處理一個文件。但讀者可以很容易把它改為一個MDI程序。雖然對於這裡的實際情況來說,似乎並無必要。 

  6.3 文件控件的應用 

  Delphi文件管理的最大特色是提供了一組文件操作控件。利用這些控件我們可以快速開發一個文件名浏覽系統。其功能強大與其所需書寫代碼之少所形成的強烈反差,正是Dephi生命力的體現。 

6.3.1 文件控件及其相互關系 

  Delphi提供的專用文件控件如下表所示。 

  表6.4 Delphi專用文件控件━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  控件名 功能

  ─────────────────────────────────────

  DriveComboBox 驅動器組合列表框。用於選擇當前驅動器

  FileListBox 文件列表框。用於顯示當前目錄中的文件和選中當前文件

  FilterComboBox 文件類型組合列表框。用於選擇顯示文件的類型

  DirectoryOutline 目錄樹(6.4節專門介紹)

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  以上控件前四個在Component Palette(部件選擇板)的System頁中,DirectoryOutline在Component Palette的Samples頁中。

  以上文件控件再加上文件編輯框、目錄標簽框(事實上是一般的編輯框、標簽框)就可以構成一個完整的文件操作系統。它們之間的聯系幾乎不用代碼支持,只要設置好相應的屬性就可以了。

  FileEdit、DirLabel、FileListBox、FileFilterComloList、 DirectoryListBox、DriveComboList六個控件間的屬性聯系如下: 
DriveComboList .DirList := DirectoryListBox;
DirectoryListBox.DirLabel := DirLabel;
DirectoryListBox.FileList := FileListBox;
FileFilterComboList.FileList := FileListBox;
FileListBox.FileEdit := FileEdit;
 

  以上聯系可以在設計時完成。只要打開相應屬性的選擇列表框進行選擇即可。也可以在運行時利用如上的賦值語句建立聯系。

  文件控件的關鍵屬性基本上都在以上聯系中反映出來了。除此之外,FileFilterComboList有一個Filter屬性,用來設置組合列表框的選擇項;FileListBox 有一個Mask屬性,用於設置顯示文件的類型,這就允許FileListBox在脫離FileFilterComboList單獨應用時仍能根據需要顯示特定的文件。在6.4節中我們將應用這一功能。

文件控件的方法、事件基本是從ListBox和ComboBox中繼承的。但FileListBox 中有一個ApplyFilePath方法很有用,我們將在後邊給出其用法。 

  6.3.2 文件名浏覽查找系統的設計思路 

  作為文件控件的應用實例,我們開發了一個簡單的文件名浏覽查找系統。這個系統可用於文件名的顯示,把選中的文件寫入列表框,並能按文件編輯框中輸入的通配符對文件進行查找。

  表6.5 部件的設計

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  部件 屬性 功能

  ─────────────────────────────────────

  FileCtrForm Position=poDefault 主窗口

  DirLabel 顯示當前目錄

  FileEdit TabOrder=0 顯示當前文件/輸入文件顯示匹配符

  FileListBox1 FileEdit=FileEdit 顯示當前目錄文件

  DirectoryListBox1 DirLabel=DirLabel 顯示當前驅動器目錄

  FileList= FileListBox1

  DriveComboBox1 DirList= DirectoryListBox1 選擇當前驅動器

  FilterComboBox1 FileList=FileListBox1 選擇文件顯示類型

  Filter='All Files(*.*)|*.*|

  Source Files(*.pas)|*.pas|

  Form Files(*.dfm)|*.dfm|

  Project Files(*.dpr)|*.dpr'

  ListBox1 顯示選中或查找的文件

  Button1 Caption='查找' 按 FileEdit 中的內容進行查找

  Button2 Caption='退出' 退出系統

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

  6.3.3 文件名浏覽查找系統的功能和實現 

  6.3.3.1 按指定後綴名顯示當前目錄中的文件 

實現這一功能只需要在控件間建立正確的聯系即可,不需要代碼支持。建立聯系的方法如(6.3.1)中的介紹。 

  6.3.3.2 把選中的文件添加到列表框中 

  在FileListBox1的OnClick事件中: 

  procedure TFileCtrForm.FileListBox1Click(Sender: TObject);
begin
if Searched then
begin
Searched := False;
ListBox1.Items.Clear;
Label5.Caption := 'Selected Files';
end;
if NotInList(ExtractFileName(FileListBox1.FileName),ListBox1.Items) then
ListBox1.Items.Add(ExtractFileName(FileListBox1.FileName));
end;

  Searched是一個全局變量,用於標明ListBox1當前顯示內容是查找的結果還是從FileListBox1中選定的文件。

  函數NotInList用於判斷待添加的字符串是否已存在於一個TStrings對象中。函數返回一個布爾型變量。

  NotInList的具體實現如下。 

  Function TFileCtrForm.NotInList(FileName: String;Items: TStrings): Boolean;
var
i: Integer;
begin
for I := 0 to Items.Count-1 do
if Items[i] = FileName then
begin
NotInList := False;
Exit;
end;
NotInList := True;
end;

  6.3.3.3 按指定匹配字符串顯示當前目錄中的文件 

  當在FileEdit中輸入一個匹配字符串,並回車,文件列表框將顯示匹配結果。這一功能在FileEdit的OnKeyPress事件中實現。 

  procedure TFileCtrForm.FileEditKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then
begin
FileListBox1.ApplyFilePath(FileEdit.Text);
Key := #0;
end;
end;


文件列表框提供的ApplyFilePath方法是解決這一問題的關鍵所在。 

  6.3.3.4 按指定匹配字符串查找當前目錄中的文件 

  為了進行比較,我們用另一種方法來實現文件的查找功能,即利用標准過程FindFirst、FindNext。FileList1與ListBox1 中的內容完全一致。

  當用戶單擊“查找”按鈕時,與FileEdit 中字符串相匹配的文件將顯示在ListBox1中。下面是實現代碼。 

  procedure TFileCtrForm.Button1Click(Sender: TObject);
var
i: Integer;
SearchRec: TSearchRec;
begin
Searched := True;
Label5.Caption := 'Search Result';
ListBox1.Items.Clear;
FindFirst(FileEdit.text,faAnyFile,SearchRec);
ListBox1.Items.Add(SearchRec.Name);
Repeat
i := FindNext(SearchRec);
If i = 0 then
ListBox1.Items.Add(SearchRec.Name);
until i <> 0;
end;

  SearchRec是一個TSearchRec類型的記錄。TSearchRec的定義如下: 

  TSearchRec = record
Fill: array[1..21] of Byte;
Attr: Byte;
Time: Longint;
Size: Longint;
Name: string[12];
end;

  在這一結構中提供了很多信息,靈活應用將給編程帶來很大方便。下面我們舉幾個例子。

  1. 檢測給定文件的大小。 

  function GetFileSize(const FileName: String): LongInt;
var
SearchRec: TSearchRec;
begin
if FindFirst(ExpandFileName(FileName), faAnyFile, SearchRec) = 0 then
Result := SearchRec.Size
else
Result := -1;
end;
 

  這一程序將在下一節中應用。

  2. 獲取給定文件的時間戳,事實上等價於FileAge函數。 

  function GetFileTime(const FileName: String): Longint;
var
SearchRec: TSearchRec;
begin
if FindFirst(ExpandFileName(FileName),faAnyFile, SearchRec) = 0 then
Result := SearchRec.Time
else
Result := -1;
end;
 

  3. 檢測文件的屬性。如果文件具有某種屬性,則 

  SearchRec.Attr And GivenAttr > 0 

  屬性常量對應的值與意義如下表: 

  表6.6 屬性常量對應的值與意義

  ━━━━━━━━━━━━━━━━━━━━

  常量 值 描述

  ─────────────────────

  faReadOnly $01 只讀文件

  faHidden $02 隱藏文件

  faSysFile $04 系統文件

  faVolumeID $08 卷標文件

  faDirectory $10 目錄文件

  faArchive $20 檔案文件

  faAnyFile $3F 任何文件

  ━━━━━━━━━━━━━━━━━━━━ 







  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved