最近同事詢問到 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
- TFDMemTable Questions - RAD Studio - Embarcadero DocWiki
-
Delphi IOUtils. Accessing and changing Directories and Files in Delphi
沒有留言:
張貼留言