【问题标题】:C: Checking the type of a file. Using lstat() and macros doesn't workC:检查文件类型。使用 lstat() 和宏不起作用
【发布时间】:2011-12-02 05:21:12
【问题描述】:

我使用 opendir() 打开一个目录,然后使用 readdir() 和 lstat() 来获取该目录中每个文件的统计信息。在此manpage 之后,我编写了无法正常工作的代码。它确实列出了当前目录中的所有文件,但无论文件是常规文件、符号链接还是目录,它都不会打印出来。

#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>

void main(){

    char* folder=".";                                     //folder to open

    DIR* dir_p;
    struct dirent* dir_element;
    struct stat file_info;

    // open directory
    dir_p=opendir(folder);

    // show some info for each file in given directory
    while(dir_element = readdir(dir_p)){

        lstat(dir_element->d_name, &file_info);          //getting a file stats

        puts(dir_element->d_name);                       // show current filename
        printf("file mode: %d\n", file_info.st_mode);

        // print what kind of file we are dealing with
        if (file_info.st_mode == S_IFDIR) puts("|| directory");
        if (file_info.st_mode == S_IFREG) puts("|| regular file");
        if (file_info.st_mode == S_IFLNK) puts("|| symbolic link");
    }

}

【问题讨论】:

  • 有人告诉过你 main() 应该返回 int 吗?

标签: c file-type stat readdir opendir


【解决方案1】:

我知道那是几年后的事了,但为了后代你做错了:
@alk 是正确的 st_mode 字段包含更多信息,例如文件类型、文件权限等
要提取文件类型,请按位并在 st_mode 字段和文件类型掩码 S_IFMT 上执行。然后检查结果是否符合您的要求。这就是 @Ernest Friedman-Hill 提到的宏的作用。 swicth 更适合进行全面检查,即

对于一个简单的案例:

     if ((file_info.st_mode & S_IFMT)==S_IFDIR) puts("|| directory");

全面检查:

       struct stat st;
       ...

      switch (st.st_mode & S_IFMT) {
        case S_IFREG:  
            puts("|| regular file");
            break;
        case S_IFDIR:
            puts("|| directory");
            break;
        case S_IFCHR:        
            puts("|| character device");
            break;
        case S_IFBLK:        
            puts("|| block device");
            break;
        case S_IFLNK: 
            puts("|| symbolic link");
            break;
        case S_IFIFO: 
            puts("|| pipe");    
            break;
        case S_IFSOCK:
            puts("|| socket");
            break;
        default:
            puts("|| unknown"); 
     }

【讨论】:

  • 这需要更多的投票。没有按位 S_IFDIR 不起作用。
【解决方案2】:

有一组宏可以解释st_mode,这比你想象的要复杂。使用它们而不是直接探测该字段:

if (S_ISREG(file_info.st_mode))
    // file is a regular file
else if (S_ISLNK(file_info.st_mode))
    // ...

还有S_ISDIRS_ISSOCK 等等。请参阅,例如,here 了解信息。

【讨论】:

    【解决方案3】:

    模式包含大量信息。

    尝试以下类型的测试:

    if (S_ISDIR(file_info.st_mode))  puts("|| directory");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-23
      • 2022-07-14
      • 2023-04-11
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      相关资源
      最近更新 更多