我已经在Delphi中实现了这个代码,它将搜索文件或给出的名称,但它省略了搜索所有子目录。怎么办呢?
代码:
if FindFirst(filePath,faAnyFile,searchResult)=0 then
try
repeat
lbSearchResult.Items.Append(searchResult.Name);
until FindNext(searchResult)<>0
except
on e:Exception do
ShowMessage(e.Message);
end; //try ends
FindClose(searchResult);
答案 0 :(得分:24)
使用Delphi XE及以上版本,您可以查看IOUtils.pas:
TDirectory.GetFiles('C:\', '*.dll', TSearchOption.soAllDirectories);
答案 1 :(得分:9)
如果您不需要线程,最简单的方法是:
procedure TForm1.AddAllFilesInDir(const Dir: string);
var
SR: TSearchRec;
begin
if FindFirst(IncludeTrailingBackslash(Dir) + '*.*', faAnyFile or faDirectory, SR) = 0 then
try
repeat
if (SR.Attr and faDirectory) = 0 then
ListBox1.Items.Add(SR.Name)
else if (SR.Name <> '.') and (SR.Name <> '..') then
AddAllFilesInDir(IncludeTrailingBackslash(Dir) + SR.Name); // recursive call!
until FindNext(Sr) <> 0;
finally
FindClose(SR);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items.BeginUpdate;
AddAllFilesInDir('C:\Users\Andreas Rejbrand\Documents\Aweb');
ListBox1.Items.EndUpdate;
end;
答案 2 :(得分:4)
最简单的方法是:
uses
DSiWin32;
DSiEnumFilesToStringList('c:\somefolder\file.name', 0, ListBox1.Items, true, true);
DSiWin32是一个免费的Delphi库。
答案 3 :(得分:1)
当我需要像tricks
那样覆盖受保护的方法时,我倾向于使用通用的解决方案来解决这个问题......我对这个类进行了攻击。
以下是TDirectoryListbox
。
在每个表单上,您需要使用此hacked
TDirectoryListbox
,只需将unitTDirectoryListbox_WithHiddenAndSystemFolders
添加到界面uses
,表单就会使用hacked
{{ 1}}。
在proyect文件夹中创建一个名为TDirectoryListbox
的文件。
将此文本放在该文件中(稍后我将解释我所做的):
unitTDirectoryListbox_WithHiddenAndSystemFolders.pas
现在我解释一下我做了什么:
unit unitTDirectoryListbox_WithHiddenAndSystemFolders;
interface
uses
Windows
,SysUtils
,Classes
,FileCtrl
;
type TDirectoryListbox=class(FileCtrl.TDirectoryListbox)
private
FPreserveCase:Boolean;
FCaseSensitive:Boolean;
protected
function ReadDirectoryNames(const ParentDirectory:String;DirectoryList:TStringList):Integer;
procedure BuildList;override;
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property PreserveCase:Boolean read FPreserveCase;
property CaseSensitive:Boolean read FCaseSensitive;
end;
implementation
constructor TDirectoryListbox.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
end;
destructor TDirectoryListbox.Destroy;
begin
inherited Destroy;
end;
function TDirectoryListbox.ReadDirectoryNames(const ParentDirectory:String;DirectoryList:TStringList):Integer;
var
TheCount,Status:Integer;
SearchRec:TSearchRec;
begin
TheCount:=0;
Status:=FindFirst(IncludeTrailingPathDelimiter(ParentDirectory)+'*.*',faDirectory or faHidden or faSysFile,SearchRec);
try
while 0=Status
do begin
if faDirectory=(faDirectory and SearchRec.Attr)
then begin
if ('.'<>SearchRec.Name)
and
('..'<>SearchRec.Name)
then begin
DirectoryList.Add(SearchRec.Name);
Inc(TheCount);
end;
end;
Status:=FindNext(SearchRec);
end;
finally
FindClose(SearchRec);
end;
ReadDirectoryNames:=TheCount;
end;
procedure TDirectoryListBox.BuildList;
var
TempPath: string;
DirName: string;
IndentLevel, BackSlashPos: Integer;
VolFlags: DWORD;
I: Integer;
Siblings: TStringList;
NewSelect: Integer;
Root: string;
begin
try
Items.BeginUpdate;
Items.Clear;
IndentLevel := 0;
Root := ExtractFileDrive(Directory)+'\';
GetVolumeInformation(PChar(Root), nil, 0, nil, DWORD(i), VolFlags, nil, 0);
FPreserveCase := VolFlags and (FS_CASE_IS_PRESERVED or FS_CASE_SENSITIVE) <> 0;
FCaseSensitive := (VolFlags and FS_CASE_SENSITIVE) <> 0;
if (Length(Root) >= 2) and (Root[2] = '\') then
begin
Items.AddObject(Root, OpenedBMP);
Inc(IndentLevel);
TempPath := Copy(Directory, Length(Root)+1, Length(Directory));
end
else
TempPath := Directory;
if (Length(TempPath) > 0) then
begin
if AnsiLastChar(TempPath)^ <> '\' then
begin
BackSlashPos := AnsiPos('\', TempPath);
while BackSlashPos <> 0 do
begin
DirName := Copy(TempPath, 1, BackSlashPos - 1);
if IndentLevel = 0 then DirName := DirName + '\';
Delete(TempPath, 1, BackSlashPos);
Items.AddObject(DirName, OpenedBMP);
Inc(IndentLevel);
BackSlashPos := AnsiPos('\', TempPath);
end;
end;
Items.AddObject(TempPath, CurrentBMP);
end;
NewSelect := Items.Count - 1;
Siblings := TStringList.Create;
try
Siblings.Sorted := True;
{ read all the dir names into Siblings }
ReadDirectoryNames(Directory, Siblings);
for i := 0 to Siblings.Count - 1 do
Items.AddObject(Siblings[i], ClosedBMP);
finally
Siblings.Free;
end;
finally
Items.EndUpdate;
end;
if HandleAllocated then
ItemIndex := NewSelect;
end;
end.
添加到接口unitTDirectoryListbox_WithHiddenAndSystemFolders
,我使表单使用修改后的(aka,uses
)组件。hacked
的受保护方法(需要修改的方法),我从单位ReadDirectoryNames
复制它,然后我在我自己的单位上编辑该副本到FileCtrl
问题(没有显示隐藏文件夹,也没有显示系统文件夹); fix
是通过在trick
部分FindFirst
之后添加来编辑对faDirectory
的调用,我还将or faHidden or faSysFile
更改为SlashSep
(避免一些额外的引用,等),并进行重新格式化(索引等),所以我可以看到该方法是我修改过的。IncludeTrailingPathDelimiter
,我只是简单地从单位BuildList
复制它而不做任何修改(如果没有复制,FileCtrl
不起作用,因为对hack
的调用位于ReadDirectoryNames
)内。BuildList
和FPreserveCase
的声明及其属性声明(它们在FCaseSensitive
方法中使用)。BuildList
会看到隐藏的和系统文件夹希望这对其他人有帮助,这样你就可以在你的项目中同时拥有TDirectoryListBox
(原始的和修改过的)(但不是同一个形式,抱歉),而根本不需要修改VCL。
TDirectoryListBox
上搜索property
并查看有多少有很多工作要加上它们,对不起给您带来任何不便。
答案 4 :(得分:0)
我在不久前发布了一个针对不同问题的解决方案:
Delphi: Copy Files from folder with Overall progress. CopyFileEx?