【问题标题】:Recursive listing递归列表
【发布时间】:2016-10-21 06:25:58
【问题描述】:

我在尝试在 C 上实现 ls -R 之类的东西时遇到了问题,问题是我需要 list 递归地列出从给定目录开始的所有内容,然后对从列表中获得的常规文件进行处理。 这是我目前所拥有的:

 void ls(char* path){
    DIR *directory;
    struct dirent *filei;
    struct stat stats;
    directory = opendir(path);
    if (directory != NULL)  
    {
        while ((filei=readdir(directory))!=NULL){
            stat(filei->d_name, &stats);    
            printf(" %s\n", filei->d_name); 
            if (S_ISDIR(stats.st_mode)){
                char *buf = malloc(strlen(path)+strlen(filei->d_name)+2);
                strcpy(buf,path);
                strcat(buf,"/");
                strcat(buf,filei->d_name);
                ls(buf);
            }
        }
        closedir(directory);
    }
    else{
        printf("Error.\n");     
    }
}

它根本不起作用,它显示的文件甚至不在我正在使用的文件夹中。 有什么想法吗? 谢谢。

【问题讨论】:

  • 这是使用文件/目录操作时的常见问题。 d_name 不是完整路径。因此,除非您的当前目录是包含该文件/目录的目录,否则您不能stat 它。 opendir 不会更改您的当前目录。在调用stat 之前需要调用chdir。或者构造一个完整的路径名。
  • 您还需要过滤掉... 条目。否则你会得到无限递归。
  • 这解决了无限递归问题,但我还不能让它工作,我不是已经用这个构建了完整的路径吗? ` char *buf = malloc(strlen(path)+strlen(filei->d_name)+2);` ` strcpy(buf,path);` strcat(buf,"/"); strcat(buf,filei->d_name);
  • 在您发布的代码中,您正确地创建了完整的路径名,但还不足以让 stat() 使用它——请参阅我对代码的修改

标签: c recursion ls


【解决方案1】:

你不能递归到“。”和“..”条目。你至少无限地递归到同一个目录,或者up很糟糕。过滤器:

if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) ls(buf);

您还必须stat 进入完整路径:

char *buf = malloc(strlen(path)+strlen(filei->d_name)+2);
strcpy(buf,path);
strcat(buf,"/");
strcat(buf,filei->d_name);
stat(buf, &stats);
if (S_ISDIR(stats.st_mode)) {
  if (!strcmp(filei->d_name,".") && (!strcmp(filei->d_name,"..")) {
    ls(buf);
  }
}

【讨论】:

    【解决方案2】:

    您的代码在完整文件路径上调用stat() 的以下返工跳过了“。”和“..”目录,修复了内存泄漏并添加了一些错误处理:

    #define SEPARATOR "/"
    
    void ls(const char *path)
    {
        DIR *directory = opendir(path);
    
        if (directory != NULL)  
        {
            struct dirent *filei;
    
            while ((filei = readdir(directory)) != NULL)
            {
                if (strcmp(filei->d_name, ".") == 0 || strcmp(filei->d_name, "..") == 0)
                {
                    continue;
                }
    
                char *buffer = malloc(strlen(path) + strlen(filei->d_name) + strlen(SEPARATOR) + 1);
                strcat(strcat(strcpy(buffer, path), SEPARATOR), filei->d_name);
    
                struct stat stat_buffer;
    
                if (stat(buffer, &stat_buffer) == 0)
                {   
                    printf("%s\n", buffer); 
    
                    if (S_ISDIR(stat_buffer.st_mode))
                    {
                        ls(buffer);
                    }
                }
                else
                {
                    perror(NULL);
                }
    
                free(buffer);
            }
    
            closedir(directory);
        }
        else
        {
            perror(NULL);     
        }
    }
    

    看看它是否更适合你。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2014-01-18
      • 2015-04-25
      相关资源
      最近更新 更多