本文整理自网络,侵删。
在目录中找文件是程序设计中的基本功之一。在应用程序中,我们要知道某个支持文件是否存在,除了在注册表中找到它的行踪外,还需要知道它处在哪个目录下。有时候,注册表中没有某些文件的目录指向,那我们就要直接从磁盘中找到它。
windows系统为我们找文件提供了一个查找功能,它是在外部执行的,我们不能在程序中调用它。
要编写一个自己的文件查找程序,需注意一下几个难点:
(1)要将制定目录细分,因为目录中有子目录,子目录中又有子目录,目录的层次是未知的,所以要将目录中的所有子目录找出来。
(2)文件有多种属性之分,有隐含文件、只读文件、存档文件等,要将它们一并找出来。
如图所示,本例写了一个通用的文件查找过程,首先在Edit1中输入要查找的目录,再在Edit2中输入要找的文件,可以用通配符*号匹配未知内容,然后按“搜索”按钮(Button控件),程序开始寻找文件,并将结果放入ListBox1中。
为此,本例写了两个重要的过程,一个是在目录中找文件过程SearcFile,它的参数规定如下:
path:目录名
filename:文件名
list:找到文件后所保存的字符串列表
procedure Tform1.SearchFile(path,filename:string;list:TStrings);var sr:TSearchRec; iAttributes:Integer;begin iAttributes:=0; iAttributes:=iAttributes or faHidden; if (FindFirst(path+''+filename,iAttributes,sr)=0) then begin list.Add(path+''+sr.Name); while (FindNext(sr)=0) do begin list.Add(path+''+sr.Name); end; FindClose(sr); end;end;这个过程中主要用到了FindFirst与FindNext函数,这是一对孪生兄弟,伴随着它们,有一个TSearchRec结构,这个结构式这样定义的:
struct TSearchRec{ int Time; //日期 int Size; //大小 int Attr; //属性 AnsiString Name;//名称 int ExcludeAttr;//额外属性 int FindHandle; //找到句柄 _WIN32_FIND_DATAA FindData; //其他附加信息,包括产生日期、修改日期、长短文件名等};在这个结构中,属性是最重要的,它有如下表所示的取值。
属性Attr的取值及说明值说明faReadOnly只读文件faHidden隐含文件,不可见faSysFile系统文件faVolumeID卷标文件faDirectory目录faArchive存档文件faAnyFile任何文件这两个函数使用后,别忘了还有一个关闭寻找功能的函数FindClose。
同样,利用FindFirst与FindNext函数,我们再写一个找目录的过程SearchPath,它的参数与上面的过程一样。
procedure Tform1.SearchPath(path,filename:string;list:TStrings);var sr:TSearchRec; iAttributes:Integer;begin iAttributes:=0; iAttributes:=iAttributes or faDirectory;</p><p> SearchFile(path,filename,list); if (FindFirst(path+'*.*',iAttributes,sr)=0) then begin if (sr.Attr = iAttributes) then begin if((sr.Name<>'.') and (sr.Name<>'..')) then begin SearchPath(path+''+sr.Name,filename,list); end; end; while (FindNext(sr) = 0) do begin if (sr.Attr = iAttributes) then begin if((sr.Name<>'.') and (sr.Name<>'..')) then begin SearchPath(path+''+sr.Name,filename,list); end; end; end; FindClose(sr); end;end;细心的读者可以看出,这是一个递归过程,什么叫递归过程?一句话,就是自己调用自己的过程。
这是最典型的递归过程(或函数)的例子,在什么情况下用递归过程,有些初学程序编写的读者可能难以掌握,想一想该例的实际情况,就是递归的最好例证。
分析一下该例的递归情况:
(1)在指定目录下查找相关文件。
(2)在指定目录下找子目录,若找到子目录,将该子目录作为制定目录,调用自己。
这就是一个不断重复调用自己找目录、找文件的过程,并且这些目录层次都是未知的,用递归的方法实现它是最好不过的了。
本函数中用FindFirst函数所赋的参数为path+"\*.*";为什么要用*.*,因为目录时未知的,在未知情况下,一般采用这种方法才能将所有目录找全。“*”在dos中是通配符的意思。
在找目录过程中,程序会找到“.”、“..”这样的目录,使用过dos的朋友一定明白,“.”代表当前目录,“..”代表上层目录,在这里忽略它就可以了。
搜索按钮Button1实现代码如下:
procedure TForm1.Button1Click(Sender: TObject);beginSearchPath(Edit1.Text,Edit2.Text,ListBox1.Items);end;
相关阅读 >>
Delphi xe 启动关闭start page 页错误提示
Delphi dbexpress的upwherekeyonly的使用注意事项
Delphi2007-Delphi2010 程序不出现在任务栏的方法
Delphi webbrowser1 保存文档为 .html
更多相关阅读请进入《Delphi》频道 >>