【问题标题】:What is the correct way to use the stat() function to test if a DIRENT is a directory or a file?使用 stat() 函数测试 DIRENT 是目录还是文件的正确方法是什么?
【发布时间】:2009-10-09 09:21:04
【问题描述】:

我在使用“if(S_IFDIR(stbuf.st_mode))”行时遇到了一些问题。这是测试要递归到的目录的正确方法吗?目前的函数似乎对 1 或 2 个循环正确,然后失败和分段错误。

我已经尝试了以下条件,并且可能更多。

S_ISDIR(st_mode)
((st_mode & ST_IFMT) == S_IFDIR)
S_IFDIR(stbuf.st_mode)

我已经包含了整个函数,因为我担心问题可能出在其他地方。

void getFolderContents(char *source, int temp){
    struct stat stbuf;
    int isDir;
    dirPnt = opendir(source);
    if(dirPnt != NULL){
        while(entry = readdir(dirPnt)){
            char *c = entry->d_name;
            if(strcmp(entry->d_name, cwd) == 0 || strcmp(entry->d_name, parent) == 0){
            }
            else{
                stat(entry->d_name, &stbuf);
                printf("%i %i ", S_IFMT, stbuf.st_mode);
                if(S_IFDIR(stbuf.st_mode)){            //Test DIR or file
                printf("DIR: %s\n", entry->d_name);
                getFolderContents(entry->d_name, 0);
            }
            printf("FILE: %s\n", entry->d_name);
        }
    }
    closedir(dirPnt);
}

【问题讨论】:

  • 正确答案请看here

标签: c function directory-structure


【解决方案1】:

是的,没错。但是由于你从不切换到目录,所以你不会找到它。

考虑以下目录层次结构:

 a
 |
 +- b
 |  |
 |  +- c
 ...

您的代码将扫描其当前目录,并找到“a”。它会判断它是一个目录,并递归调用自己,并打开“a”进行读取。这行得通。该扫描将找到一个名为“b”的目录,但尝试仅使用条目名称打开它会失败,因为路径现在是“a/b”。

我建议在打开它之前切换到目录(使用@987654321@)。这意味着你可以opendir(".")。存储旧路径,并在递归该级别完成时再次将chdir() 输出(而不是在进行递归调用以更深入之前)。

【讨论】:

  • 嗯,这不能解释 SEGFAULT 吗?
  • 当测试入口结构并发现它是一个目录时,我再次递归调用该函数,然后打开该目录路径。
  • 你的意思是我需要包含我开始使用的目录的完整相对路径吗?
  • 您的进程只有一个“当前目录”。所有非绝对文件操作都是以此为基础完成的。如果您在“a”上执行 opendir(),然后在“b”上执行 opendir,则没有什么意味着“a/b”。您需要调用 chdir() 使扫描的目录成为当前目录,然后调用 opendir(".") 和递归。
【解决方案2】:

条目在哪里定义?它是局部变量吗? 我不明白为什么它会出现段错误,但可能你应该将它设为局部变量。 它会咬你的一个例子是:

                    if(S_IFDIR(stbuf.st_mode)){            //Test DIR or file
                            printf("DIR: %s\n", entry->d_name);
                            getFolderContents(entry->d_name, 0);
                    }
                    printf("FILE: %s\n", entry->d_name);

printf 会打印错误的名称,所以你应该在这里添加一个 else。

dirpnt 也是如此。当您在 while 循环中退出 getFolderContents 时, 你最终会在一个封闭的 dirpoint 上调用 readdir,这应该会让你脱离循环。

但正如 bahbar 所说: 您不能在全局变量中递归和存储临时变量

【讨论】:

  • struct dirent *entry;这是在 main() 之前定义的
  • 您不能在全局中递归和存储临时值。将 entry 和 dirPnt 作为局部变量
  • 谢谢 Bahbar 我认为这让我很退缩。它现在工作得更好,但只递归一个文件夹。
猜你喜欢
  • 2019-06-13
  • 1970-01-01
  • 2015-02-21
  • 2021-12-19
  • 2011-09-08
  • 2021-03-24
  • 1970-01-01
  • 2019-01-12
相关资源
最近更新 更多