我正在编写一个搜索给定目录的所有子目录的程序。问题是,我知道我要查找的文件的名称(data.txt),但我仍然需要知道文件所在的所有(可能是多个)位置。我正在使用此代码进行搜索:
struct dirent *dp;
struct stat s;
DIR *dir;
char path[]="/some/path/here/";
if((dir=opendir(path))==NULL){return;}
while((dp=readdir(dir))!=NULL){
char *temp=malloc((strlen(path)+strlen(dp->d_name)+4)*sizeof(*temp));
sprintf(temp,"%s%s",path,dp->d_name);//concatenate path
lstat(temp,&s);//stat the path
if(S_ISREG(s.st_mode)){//if regular file
if(!strcmp(dp->d_name,"data.txt")){
printf("found one: %s\n",temp);//found the target file
}
}else if(S_ISDIR(s.st_mode) && !S_ISLNK(s.st_mode)){//if directory, but not symlink
if(strcmp(dp->d_name,".") && strcmp(dp->d_name,"..")){//ignore "." and ".."
//recurse on the subdirectories
}
}
free(temp);
}
closedir(dir);
代码工作正常但仍然非常快,但我仍然觉得lstat
- 文件系统中的每个文件/目录只是为了寻找目录是非常低效的。
是否有更有效的搜索方式,以便只通过readdir
返回目录?
我在Fedora 13上使用gcc
答案 0 :(得分:2)
ftw()(或nftw())是实现类似find的函数的调用。
需要stat或lstat的原因是要知道你有什么文件类型 - 常规,链接, 目录等。
将“data.txt”作为目录,链接和常规文件是可能的,尽管根本不可能。你必须能够将它排序以获得你想要的东西。 ftw()将一个stat struct *返回给一个回调函数 - 这是ftw()的一个参数。
答案 1 :(得分:2)
不要在每个返回的值上使用lstat
,而是使用dirent
的{{1}}字段(请参阅readdir
手册页),例如
d_type
答案 2 :(得分:0)
您可以尝试读取linux find
命令的来源。
答案 3 :(得分:0)
您可能希望查看glob
函数,听起来您可能正在尝试重新实现它。