我的磁盘遍历算法为什么没有微软的的快,我不明白速度慢在那里?

Siney 2003-03-20 06:09:37
先看我的整个遍历模块

//遍历磁盘
//Aweay 2003-2-10
#ifndef BROWSEDIR
#define BROWSEDIR
#include <vcl.h>
#include <windows.h>
#include <Classes.hpp>

#define BD_FIND_DIR 0
#define BD_FIND_FILE 1
#define BD_FIND_COMPLETE 2 //查询完毕
#define BD_FIND_ABORT 3 //查询中断

//Error define
#define BD_ERR_OK 0
#define BD_ERR_NOFILTER 1
#define BD_ERR_NOCALLBACK 2
#define BD_ERR_NOTARGET 3

//Thread
#define BD_EXIT_NORMAL 0
#define BD_EXIT_ABORT 1

typedef void __fastcall (__closure *BDCallBack)(String path,int type); //回调函数类型

class TBrowseDir : public TThread //遍历整个磁盘的类
{
protected:
void __fastcall Execute();
private:
TStringList* lstDir; //用于保存临时目录
TStringList* lstFilter; //保存多种查找目标
TStringList* lstTarg;
BDCallBack lpFunc; //当找到目标时将调用这个函数指针指向的函数
String PathString(String pn); //返回带\\结尾的文件夹名称
int SearchDir(String dir);
WIN32_FIND_DATA filedata;
String tmpFn;
int tmpType;
void __fastcall CallBack();
void OnFind(String fn, int n);
int AddSubDir(String strParent);
public:
TBrowseDir(bool CreateSuspended);
__fastcall virtual ~TBrowseDir(void);
void SetCallBack(BDCallBack lpF);
void AddFilter(String strFil);
int Find();
void AddFilte(TStringList* lstF);
void AddTarget(String dir);
};

TBrowseDir::TBrowseDir(bool CreateSuspended)
:TThread(CreateSuspended)
{
//TODO: Add your source code here
lstDir=new TStringList();
lstFilter=new TStringList();
lstTarg=new TStringList();
lpFunc=NULL;
}

__fastcall TBrowseDir::~TBrowseDir()
{
//TODO: Add your source code here
delete lstDir;
delete lstFilter;
delete lstTarg;
}
/*设置回调函数,函数的类型为BDCallBack,原形如下
typedef void __fastcall (__closure *BDCallBack)(String path,int type)
当找到文件或文件夹或查找完毕将调用这个函数。
其中:
path 根据type不同表示找到的文件或文件夹,如果type返回BD_FIND_COMPLETE,则path为空
type 可以取值
BD_FIND_FILE 找到文件
BD_FIND_DIR 找到文件夹
BD_FIND_COMPLETE 查找完毕
*/
void TBrowseDir::SetCallBack(BDCallBack lpF) //设置回调函数
{
//TODO: Add your source code here
lpFunc=lpF;
}

void TBrowseDir::AddFilter(String strFil) //添加一种查找类型,例如*.txt
{
//TODO: Add your source code here
lstFilter->Add(strFil);
}

/*
用于遍历磁盘的主函数
dir表示要遍历的磁盘目录,比如"c:\\"
调用Find函数之前需要调用AddFilter函数和SetCallBack函数
*/
int TBrowseDir::Find() //查找/遍历文件夹
{
//TODO: Add your source code here
if(lstFilter->Count<=0)
return BD_ERR_NOFILTER;
if(lpFunc==NULL)
return BD_ERR_NOCALLBACK;
if(lstTarg->Count<=0)
return BD_ERR_NOTARGET;

memset(&filedata,0,sizeof(filedata));
Resume();
return BD_ERR_OK;
}

String TBrowseDir::PathString(String pn)
{
//TODO: Add your source code here
if(pn.SubString(pn.Length(),1)=="\\")
return pn;
else
return pn+String("\\");
}

int TBrowseDir::SearchDir(String dir)
{
//TODO: Add your source code here
HANDLE re;
for(int n=0;n<lstFilter->Count;n++)
{
String findit=lstFilter->Strings[n];
re=FindFirstFile(findit.c_str(),&filedata);
if(re!=INVALID_HANDLE_VALUE)
{
if(strcmp(filedata.cFileName,"..")!=0
&& strcmp(filedata.cFileName,".")!=0) //如果时文件夹并且不是上一层文件夹和自身
{
if((filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=0)
lstDir->Add(dir+String(filedata.cFileName));
else //找到了文件
OnFind(dir+filedata.cFileName,BD_FIND_FILE);
}
while(FindNextFile(re,&filedata))
{
if(Terminated) //处理用户终止
return BD_EXIT_ABORT;

if(strcmp(filedata.cFileName,"..")!=0
&& strcmp(filedata.cFileName,".")!=0)
{
if((filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=0)
lstDir->Add(dir+String(filedata.cFileName));
else
OnFind(dir+String(filedata.cFileName),BD_FIND_FILE);
}
}
}
FindClose(re); //释放
}
return BD_EXIT_NORMAL;
}

void __fastcall TBrowseDir::Execute()
{
//---- Place thread code here ----
for(int m=0;m<lstTarg->Count;m++)
{
String strDir=PathString(lstTarg->Strings[m]);
OnFind(strDir,BD_FIND_DIR);
AddSubDir(strDir);//添加子文件夹
SetCurrentDirectory(strDir.c_str());
int re=SearchDir(strDir);
if(re==BD_EXIT_ABORT)
{
OnFind("",BD_FIND_ABORT);
return;
}
int n=lstDir->Count;
while(n>0) //如果n>0证明还有文件夹没有扫描
{
String dn=PathString(lstDir->Strings[0]);
OnFind(dn,BD_FIND_DIR);
re=AddSubDir(dn);
if(re==BD_EXIT_ABORT)
{
OnFind("",BD_FIND_ABORT);
return;
}
SetCurrentDirectory(dn.c_str()); //设置当前工作目录
lstDir->Delete(0);
re=SearchDir(dn);
if(re==BD_EXIT_ABORT)
{
OnFind("",BD_FIND_ABORT);
return;
}
n=lstDir->Count;
}
}
OnFind("",BD_FIND_COMPLETE);
}

void __fastcall TBrowseDir::CallBack() //调用回调函数
{
//TODO: Add your source code here
lpFunc(tmpFn,tmpType);
}

void TBrowseDir::OnFind(String fn, int n)
{
//TODO: Add your source code here
tmpFn=fn;
tmpType=n;
Synchronize(CallBack); //VCL多线程阻塞
}
void TBrowseDir::AddFilte(TStringList* lstF) //重载方法
{
//TODO: Add your source code here
lstFilter->AddStrings(lstF);
}

int TBrowseDir::AddSubDir(String strParent) //添加strParent下的子目录
{
//TODO: Add your source code here
TSearchRec fileinfo;
memset(&fileinfo,0,sizeof(fileinfo));
int re=FindFirst(strParent+"*.*",faDirectory,fileinfo);
if(re==0)
{
if((fileinfo.Attr & faDirectory)!=0
&& fileinfo.Name!="."
&& fileinfo.Name!="..")
lstDir->Add(strParent+fileinfo.Name);
while(FindNext(fileinfo)==0)
{
if(Terminated)
return BD_EXIT_ABORT;
if((fileinfo.Attr & faDirectory)!=0
&& fileinfo.Name!="."
&& fileinfo.Name!="..")
lstDir->Add(strParent+fileinfo.Name);
}
}
FindClose(fileinfo);
return BD_EXIT_NORMAL;
}

void TBrowseDir::AddTarget(String dir)
{
//TODO: Add your source code here
lstTarg->Add(dir);
}
#endif


用我以上的算法遍历一个10g的硬盘(及指定*.*搜索)需要用50秒,而windows自带的查找文件功能查找*.*文件只需要20秒钟的时间???

为了提高速度,我没有采用递归算法,而且尽量使用API函数,可是还是有这么大的差距。

望高手指教。。。
...全文
48 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Chxis 2003-03-21
  • 打赏
  • 举报
回复
同算法都有关系吧?
Siney 2003-03-21
  • 打赏
  • 举报
回复
原来如此,啊
mustang_zr 2003-03-21
  • 打赏
  • 举报
回复
同意楼上

微软自己的查询程序肯定是经过优化的
jishiping 2003-03-20
  • 打赏
  • 举报
回复
Windows NT/2000/XP,有一个叫“Indexing Service”的服务,启动它的话,搜索的速度
就会加快。因为操作系统自己管理的原故,他自己使用了缓冲。就是说,第一次查询比较
慢,但是它会将查询的结果保存在内存里,以后查询的速度就快了。当新建文件,删除文
件,移动文件时,而这些操作,系统会自动更新内存里的内容。但是自己写的程序,就没
有这些先天的优势了,速度自然比不上操作系统的搜索速度。
  • 打赏
  • 举报
回复
What's "内存查询"?
netsys2 2003-03-20
  • 打赏
  • 举报
回复
windows自带的查找文件功能带有内存查询,当然快了。
特别是第二次查询,暴快
halibut 2003-03-20
  • 打赏
  • 举报
回复
up!

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧