如何用TDirectory.GetFiles获取文件夹最新文件?现有代码存问题
问题:用TDirectory.GetFiles获取最新文件失败,该如何处理?
我原本想通过调用TDirectory.GetFiles获取文件夹里最新文件的名称,写了下面这段代码,但它没法稳定返回最新文件名——原因是谓词函数不是按时间戳顺序执行的。请问能不能用TDirectory实现这个需求,还是必须改用FindFirst?
var FLastTime: TDateTime; searchResults: TArray<String>; begin FlastTime := 0; FPollDir := 'c:\tempfiles'; FFileExt := '*.xlsx'; searchResults := TDirectory.GetFiles(FPollDir, FFileExt, TSearchOption.soTopDirectoryOnly, function(const Path: String; const SearchRec: TSearchRec): Boolean begin if (SearchRec.TimeStamp > FLastTime) then begin FLastTime := SearchRec.TimeStamp; Result := True; end; end);
解决方案
方案一:继续使用TDirectory实现
你的原代码思路有误,试图在谓词函数里实时筛选最新文件,但谓词的执行顺序不遵循文件时间戳排序,所以无法保证结果正确。正确做法是先获取所有符合条件的文件,再从中筛选出时间最新的:
基础遍历版
var Files: TArray<String>; LatestFile: String; LatestTime: TDateTime; FileInfo: TFileInfo; begin LatestTime := 0; LatestFile := ''; Files := TDirectory.GetFiles('c:\tempfiles', '*.xlsx', TSearchOption.soTopDirectoryOnly); for const FilePath in Files do begin FileInfo := TFile.GetInfo(FilePath); if FileInfo.TimeStamp > LatestTime then begin LatestTime := FileInfo.TimeStamp; LatestFile := FilePath; end; end; // LatestFile即为最新文件的完整路径 end;
排序取首版
如果使用Delphi XE及以上版本,可借助泛型排序实现更简洁的写法:
uses System.Generics.Collections, System.Generics.Defaults; var Files: TArray<String>; LatestFile: String; begin Files := TDirectory.GetFiles('c:\tempfiles', '*.xlsx', TSearchOption.soTopDirectoryOnly); if Length(Files) > 0 then begin // 按文件时间戳降序排序,最新的文件排在首位 TArray.Sort<String>(Files, TComparer<String>.Construct( function(const A, B: String): Integer var TimeA, TimeB: TDateTime; begin TimeA := TFile.GetInfo(A).TimeStamp; TimeB := TFile.GetInfo(B).TimeStamp; Result := CompareDateTime(TimeB, TimeA); end)); LatestFile := Files[0]; end; end;
方案二:改用FindFirst/FindNext实现高效遍历
如果目标文件夹内文件数量较多,先获取所有文件再处理会占用较多内存,此时用FindFirst+FindNext遍历的方式更高效,遍历过程中直接记录最新文件即可:
var SearchRec: TSearchRec; LatestFile: String; LatestTime: TDateTime; begin LatestTime := 0; LatestFile := ''; if FindFirst('c:\tempfiles\*.xlsx', faAnyFile - faDirectory, SearchRec) = 0 then begin try repeat if (SearchRec.TimeStamp > LatestTime) then begin LatestTime := SearchRec.TimeStamp; LatestFile := 'c:\tempfiles\' + SearchRec.Name; end; until FindNext(SearchRec) <> 0; finally FindClose(SearchRec); end; end; // LatestFile即为最新文件路径 end;
总结
- 若文件夹文件数量少,优先选
TDirectory方案,代码简洁易读; - 若文件夹文件数量大,选
FindFirst/FindNext方案,内存占用更低、效率更高。
内容的提问来源于stack exchange,提问作者Freddie Bell
相关产品推荐
相关产品推荐

