C:检查文件类型。使用 lstat() 和宏不起作用

发布于 2024-12-08 05:01:51 字数 1141 浏览 0 评论 0原文

我使用 opendir() 打开一个目录,然后使用 readdir() 和 lstat() 来获取该目录中每个文件的统计信息。按照这个手册页,我编写了代码,但它并不像想象的那样工作。它确实列出了当前目录中的所有文件,但不会打印出该文件是常规文件、符号链接还是目录。

#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");
    }

}

I use opendir() to open a directory and then readdir() and lstat() to get the stats of each file in that directory. Following this manpage I wrote the code under which doesn't work as thought. It does list all the files in the current directory but it doesn't print out whever the file is a regular file, a symlink or a directory.

#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");
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤凫 2024-12-15 05:01:51

我知道已经是几年后的事了,但对于子孙后代来说,你做错了:
@alk 是对的,st_mode 字段包含更多信息,例如文件类型、文件权限等
要提取文件类型,请对 st_mode 字段和文件类型掩码 S_IFMT 执行按位与操作。然后检查结果是否符合您的要求。这就是 @Ernest Friedman-Hill 提到的宏的作用。开关更适合进行全面检查,即

对于一个简单的情况:

     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"); 
     }

I Know it is years later but for posterity you were doing it wrong:
@alk was right the st_mode field carries more info e.g file type,file permissions,etc
To extract file type you perform bitwise and on the st_mode field and the file type mask S_IFMT .Then check the result for whatever you wanted. That is what the macros mentioned by @Ernest Friedman-Hill do. A swicth is better suited for a comprehensive check i.e

for a simple case:

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

for a comprehensive check:

       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"); 
     }
感性 2024-12-15 05:01:51

有一组宏来解释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 等等。例如,请参阅此处了解信息。

There are a set of macros to interpret st_mode, which is more complex than you think. Use them instead of probing the field directly:

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

There's also S_ISDIR, S_ISSOCK, and a few more. See, e.g., here for info.

单调的奢华 2024-12-15 05:01:51

模式携带大量信息。

尝试以下测试:

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

Mode carries lots of info.

Try the following kind of test:

if (S_ISDIR(file_info.st_mode))  puts("|| directory");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文