2021/09/10

Delphi XE 存取目錄檔案清單、和排序方式


 

最近同事詢問到 Delphi 如何讀出檔案時間,而版本為 Delphi 7,網路資料很多,Google 一找一大把,但關於 XE 以上的新版本卻找不到什麼資料,究竟新版 Delphi 有沒有更好的解法呢?

這問題可以拆分為:

  • 讀取目錄檔案
  • 讀取檔案時間
  • 儲存檔案清單(含時間)
  • 排序檔案清單

有了以上步驟後,各別突破就簡單了。😉

讀取磁碟資料在 XE 後,為了跨平台特別設計了【IOUtils】單元,目的在各家平台都能使用相同程式碼讀取其儲存媒體內容,所以 IOUtils 是非常值得投資學習的單元。

讀取目錄檔案

IOUtils.TDirectory 是讀取目錄結構的物件,只要使用 GetFiles 就可以讀出目錄內所有檔案,簡單程式碼如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var
  LFileList: TStringDynArray;
  LFile: string;
begin
  LFileList := IOUtils.TDirectory.GetFiles('D:\Eden的目錄');
  for LFile in LFileList do
  begin
    ListBox1.Items.Add(LFile);
  end;
end;


讀取檔案時間

取得檔案路徑後,就可以依序取得它們的時間,在 IOUtils 中,TFile 物件可以取得以下時間

  • GetCreationTime: 檔案建立時間
  • GetLastAccessTime: 檔案最後讀取時間
  • GetLastWriteTime: 檔案最後寫入時間

以「檔案建立時間」為例,簡單程式碼如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var
  LFileList: TStringDynArray;
  LFile: string;
begin
  LFileList := IOUtils.TDirectory.GetFiles('D:\Eden的目錄');
  for LFile in LFileList do
  begin
    ListBox2.Items.Add(DateTimeToStr(IOUtils.TFile.GetCreationTime(LFile)));
  end;
end;


儲存檔案清單(含時間)

有了檔案和時間清單,就要進行兩者的結合,使用快取資料集是不錯的選擇,Delphi 內建的快取資料集有兩個:

  • TClientDataSet
  • TFdMemTable

TFdMemTable 是比 TClientDataSet 更為輕巧的資料集物件,而 TClientDataSet 則是經典物件,選擇上看個人喜好,設計上大同小異。簡單程式碼如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var
  LFilePos: Integer;
begin
  with ClientDataSet1.FieldDefs do
  begin
    Add('File', ftWideString, 200);
    Add('CreationTime', ftDateTime);
  end;
  ClientDataSet1.CreateDataSet;
  ClientDataSet1.LogChanges := False;
  ClientDataSet1.IndexFieldNames := 'CreationTime;File';
  for LFilePos := 0 to ListBox1.Items.Count-1 do
  begin
    ClientDataSet1.Append;
    ClientDataSet1.Fields[0].Value := ListBox1.Items[LFilePos];
    ClientDataSet1.Fields[1].Value := ListBox2.Items[LFilePos];
    ClientDataSet1.Post;
  end;
  ClientDataSet1.First;
  while not ClientDataSet1.Eof do
  begin
    ListBox3.Items.Add(Format('%s, %s', [ClientDataSet1.Fields[0].AsString, ClientDataSet1.Fields[1].AsString]));
    ClientDataSet1.Next;
  end;
end;


使用 TFdMemTable 請注意

TFdMemTable 預設不會記錄資料歷程 (TFdMemTable.CachedUpdates default value is False),故 LogChanges 該行程式碼要刪除。


排序檔案清單

ClientDataSet1.IndexFieldNames 屬性設定好以時間欄位排序,即可得到理想的結果,如果要倒序,則可以參閱【【Delphi】ClientDataSet 的排序】,裡面有詳細的解說。


資料集太大?泛型物件也可以

如果認為資料集物件過於龐大,則可以考慮使用泛型物件,在這裡使用 Generics.Collections 單元裡的 TDictionary 物件,目的是它可以存放 Key=Value 字典,在這個場合可以存放兩種值,適合使用 TDictionary 物件。

搭配 TArray 處理排序功能便可以取代資料集的設計方式,完整程式碼如下:


結論時間

在 Windows 平台下找尋 Win32 API 是一件再正常不過的事情了,但進入到 64 位元或是行動裝置等平台後,以往的開發習慣也要跟著一起改變,Delphi 隨著科技的更新也一同進步,你不需要 Win64 API、Android API、MacOS API、iOS API 等全部自行實作一次,只需要在設計程式上跟著 Delphi 轉換開發思維,如前面的範例所述,不僅僅是 API 上的改變,框架的整合應用也是重要且必學的技術,本文提供了硬體存取和資料庫存取的綜合應用,期待你的發揮 ❤


和你分享 😉


See also


沒有留言:

張貼留言