c - 在 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);
}
}
}
解决方案
问题是路径不正确。
使用错误处理,perror
导致错误消息lstat: No such file or directory
C 中的 Prober 错误处理非常重要,解决方案是使用绝对路径而不是相对路径的以下代码:
if(lstat("/home/foo/CLionProjects/untitled2/testdir/", &attr)==0) {
perror("lstat");
}
推荐阅读
- python - 用字符串计算矩阵上的 nan 值的数量
- javascript - Moment js 给出了意想不到的日期
- java - 使用嵌套模块打包多模块 Maven
- sql - 在 SQL 中连接行和列
- django - from django.db import models in models.py 但在命令提示符下我得到 NameError: name 'model' is not defined
- python - 线性规划 - 最大值优化
- azure - 不确定如何注册可以拥有自己的 onedrive 文件夹的 Azure AD 应用程序
- python - Powell 方法 Scipy 中的边界
- r - 在 R 中使用 apply() 计算每列范围内的单元格数
- c# - ServiceStack IoC/DI:在容器中注册类 - 如何注册所有实现特定接口的类