检查 readdir 返回的 dir. 条目是否是目录、链接或文件。dent->d_type 没有显示类型
- 2024-10-28 08:37:00
- admin 原创
- 55
问题描述:
我正在编写一个在 Linux shell 中运行的程序,它接受一个参数(一个目录),并显示目录中的所有文件及其类型。
输出应该是这样的:
<< ./Program testDirectory
Dir directory1
lnk linkprogram.c
reg file.txt
如果没有参数,则使用当前目录。这是我的代码:
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
struct stat info;
DIR *dirp;
struct dirent* dent;
//If no args
if (argc == 1)
{
argv[1] = ".";
dirp = opendir(argv[1]); // specify directory here: "." is the "current directory"
do
{
dent = readdir(dirp);
if (dent)
{
printf("%c ", dent->d_type);
printf("%s
", dent->d_name);
/* if (!stat(dent->d_name, &info))
{
//printf("%u bytes
", (unsigned int)info.st_size);
}*/
}
} while (dent);
closedir(dirp);
}
//If specified directory
if (argc > 1)
{
dirp = opendir(argv[1]); // specify directory here: "." is the "current directory"
do
{
dent = readdir(dirp);
if (dent)
{
printf("%c ", dent->d_type);
printf("%s
", dent->d_name);
/* if (!stat(dent->d_name, &info))
{
printf("%u bytes
", (unsigned int)info.st_size);
}*/
}
} while (dent);
closedir(dirp);
}
return 0;
}
由于某种原因,dent->d_type
无法显示文件类型。我不太清楚该怎么办,有什么建议吗?
解决方案 1:
d_type
`lstat(2)`当支持时,是一种速度优化,可以节省通话量。
正如readdir
(3) 手册页所指出的那样,并非所有文件系统都会在字段中返回真实信息d_type
(通常是因为需要额外的磁盘寻道来读取 inode,如果您不使用 XFS,情况就是如此mkfs.xfs -n ftype=1
(暗示-m crc=1
这还不是默认值)。始终设置的文件系统DT_UNKNOWN
在现实生活中很常见,并不是您可以忽略的东西。XFS 并不是唯一的例子。
如果文件名本身不足以决定它不有趣,您始终需要能够回退到使用lstat
(2) 的代码。(对于某些调用者来说就是这种情况,例如或扩展 glob 之类的,这就是为什么如果它需要额外的磁盘读取,则不会产生填充它的开销。)d_type==DT_UNKNOWN
`find -name*.c
readdir`
Linuxgetdents(2)
手册页有一个示例程序,可以执行您要执行的操作,其中包括一个链式三元运算符块,用于将字段解码d_type
为文本字符串。 (正如其他答案指出的那样,您的错误是将其打印为字符,而不是将其与DT_REG
、DT_DIR
等进行比较。)
无论如何,其他答案大多涵盖了内容,但忽略了关键细节,即您需要对以下情况进行回退d_type == DT_UNKNOWN
:(Linux 上的 0 d_type
存储在以前的填充字节中,直到 Linux 2.6.4)。
为了便于移植,您的代码需要检查是否使用struct dirent
了某个d_type
字段,否则您的代码甚至无法在 GNU 和 BSD 系统之外进行编译。(请参阅readdir(3)
)
我编写了一个使用 readdir 查找目录的示例,并使用d_type
回退到stat
编译时 d_type 不可用的情况、DT_UNKNOWN 的情况以及符号链接的情况。
解决方案 2:
返回结构d_type
中的数字表示类型。您无法直接打印该数字,因为使用的值在解释为 ASCII 时不可打印(例如,对于目录,它们是 4,对于文件,它们是 8)。
您可以像这样将它们打印为数字:
printf("%d ", dent->d_type)
或者将它们与常量进行比较DT_DIR
并从中构建一些有意义的输出,例如 char 类型:
if(dent->type == DT_DIR) type = 'd'
解决方案 3:
像这样打印d_type
为整数:
printf("%d ", dent->d_type);
你会看到有意义的价值观。
解决方案 4:
我可以在 ubuntu 上使用 d_type:
switch (readDir->d_type)
{
case DT_DIR:
printf("Dir: %s
", readDir->d_name);
break;
case DT_REG:
printf("File: %s
", readDir->d_name);
break;
default:
printf("Other: %s
", readDir->d_name);
}
条目类型列表可以在 dirent.h 中找到(对于除 ubuntu 之外的操作系统,这可能有所不同):
目录
#define DT_UNKNOWN 0
#define DT_FIFO 1
#define DT_CHR 2
#define DT_DIR 4
#define DT_BLK 6
#define DT_REG 8
#define DT_LNK 10
#define DT_SOCK 12
#define DT_WHT 14
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件