Эффективный поиск в файловой системе - PullRequest
1 голос
/ 22 июня 2010

Я пишу программу, которая просматривает все подкаталоги данного каталога.Проблема в том, что я знаю имя файла, который я ищу (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?

возвращались только каталоги * Я использую gcc на Fedora 13

Ответы [ 4 ]

2 голосов
/ 22 июня 2010

ftw () (или nftw ()) - это вызовы для реализации функции поиска типа.

Причина, по которой требуется stat или lstat, состоит в том, чтобы знать, какой у вас тип файла - обычный, ссылка, каталоги т. д.

Возможно, хотя и маловероятно, что data.txt будет каталогом, ссылкой и обычным файлом.Вы должны быть в состоянии разобраться, чтобы получить то, что вы хотите.ftw () возвращает stat * структуры для функции обратного вызова, которая является аргументом для ftw ().

2 голосов
/ 22 июня 2010

Вместо использования lstat для каждого возвращаемого значения используйте поле dirent d_type (см. Справочную страницу readdir), например

while((dp=readdir(dir))!=NULL){
    ...
    if (dp->d_type == DT_REG)
    {
      /* handle regular file */
    }
    else if (dp->d_type == DT_DIR)
    {
      /* handle directory */
    }
}
0 голосов
/ 22 июня 2010

Возможно, вы захотите взглянуть на функцию glob, похоже, вы пытаетесь ее реализовать.

0 голосов
/ 22 июня 2010

Вы можете попробовать прочитать источники команды linux find.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...