首页 > 解决方案 > 在 c 中使用 lstat 获取 st_mode 时,文件对于 S_IFDIR 来说是真的,即使它只是一个纯文本文件

问题描述

在以下测试目录上使用 opendir() 时

drwxrwxr-x 2 foo foo 4096 Mai  4 22:55 ./
drwxrwxr-x 5 foo foo 4096 Mai  4 22:59 ../
-rw-rw-r-- 1 foo foo   21 Mai  4 21:46 bar
-rw-rw-r-- 1 foo foo   18 Mai  4 21:46 baz.txt
-rw-rw-r-- 1 foo foo   12 Mai  4 21:45 foo
-rw-rw-r-- 1 foo foo    6 Mai  4 23:06 test.txt

并遍历每个文件

while (0 != (dirEntry = readdir(dirHandle))) { // loop over each file

在每个文件上使用 lstat 并将结果存储在attr类型的结构中stat

struct stat attr;
lstat(dirEntry->d_name, &attr);

以下代码导致无法理解的行为

if (attr.st_mode & S_IFREG) { ... }

false:在文件 bar 和 baz.txt 和 foo 上的结果为 0,没有常规文件。

if (attr.st_mode & S_IFDIR) { ... }

结果是一个等于 S_IFDIR 的数字,因此该文件是一个文件夹,即使它只包含一些文本。

不知何故,test.txt 结果都是 0。

为什么会这样?为什么纯文本文件是目录,与常规文件有什么区别?

所有只是用 vim 创建的文本文件。

我在想,在 Linux 中,所有文件夹都是文本文件,但是,如果可能的话,我需要使用上述方法将它们与普通文件区分开来。

资源



#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
// OPENDIR
#include <sys/types.h>
#include <dirent.h>

struct dirent *dirEntry;
int main(int argc, char *argv[]) {
    struct stat mainStat;

    // Check usage
    if(argc < 2) {
        printf("Usage\n");
        return EXIT_FAILURE;
    }
    if (lstat(argv[1], &mainStat) == -1) {
        perror("lstat");
        exit(EXIT_FAILURE);
    }

    DIR *dirHandle;

    // Open the directory
    dirHandle = opendir(argv[1]);
    double size;
    // if 0 retrurn, error
    if(dirHandle) {
        while (0 != (dirEntry = readdir(dirHandle))) { // loop over each file
            // Check if the file is a directory
            struct stat attr;

            lstat(dirEntry->d_name, &attr);
            printf("%s: v:%d 1:%d2:%d \n", dirEntry->d_name, (attr.st_mode & S_IFREG), attr.st_mode, S_IFREG);

            if (strcmp(dirEntry->d_name, "..") == 0 || strcmp(dirEntry->d_name, ".") == 0) {
                continue;
            }
            printf("%s: v:%d 1:%d2:%d \n", dirEntry->d_name, (attr.st_mode & S_IFDIR), attr.st_mode, S_IFDIR);
        }
    }
}

标签: clinuxfilesystemsstat

解决方案


问题是路径不正确。

使用错误处理,perror导致错误消息lstat: No such file or directory

C 中的 Prober 错误处理非常重要,解决方案是使用绝对路径而不是相对路径的以下代码:

 if(lstat("/home/foo/CLionProjects/untitled2/testdir/", &attr)==0) {
     perror("lstat");
 }

推荐阅读