Bar*_*ers 8 c linux dirent.h readdir opendir
我正在制作一个在Linux shell中运行的程序,并接受一个参数(一个目录),并显示目录中的所有文件及其类型.
输出应该是这样的:
<< ./Program testDirectory
Dir directory1
lnk linkprogram.c
reg file.txt
Run Code Online (Sandbox Code Playgroud)
如果没有参数,则使用当前目录.这是我的代码:
#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 \n", dent->d_name);
/* if (!stat(dent->d_name, &info))
{
//printf("%u bytes\n", (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 \n", dent->d_name);
/* if (!stat(dent->d_name, &info))
{
printf("%u bytes\n", (unsigned int)info.st_size);
}*/
}
} while (dent);
closedir(dirp);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因dent->d_type,不显示文件类型.我不确定该怎么办,有什么建议吗?
Pet*_*des 21
d_type是一种速度优化lstat(2),可以在支持时保存通话.
正如readdir(3)手册页指出的那样,并非所有文件系统都在该d_type字段中返回实际信息(通常是因为需要额外的磁盘搜索来读取inode,如果您不使用XFS的情况就是如此mkfs.xfs -n ftype=1(暗示-m crc=1哪个)还不是默认值.总是设置的文件系统DT_UNKNOWN在现实生活中很常见,而不是你可以忽略的东西.XFS不是唯一的例子.
你总是需要的代码,将回退到使用lstat(2)如果d_type==DT_UNKNOWN,如果单独的文件名是不够的,决定它的无趣.(对于某些呼叫者来说就是这种情况,比如find -name扩展整数*.c,这就是为什么readdir如果需要额外的磁盘读取就不会产生填充的开销.)
Linux getdents(2)手册页有一个示例程序,可以执行您要执行的操作,包括一个链式三元运算符块,用于将d_type字段解码为文本字符串.(至于其他的答案指出,你的错误是打印出来作为一个字符,而不是它比较对DT_REG,DT_DIR等等)
无论如何,其他的答案大多覆盖的东西,但错过了关键的细节,你需要一个备用当箱子d_type == DT_UNKNOWN(0在Linux上. d_type存储在曾经被认为是一个填充字节,直到Linux的2.6.4).
为了便于移植,您的代码需要检查struct dirent即使是一个d_type字段,如果您使用它,或者您的代码甚至不会在GNU和BSD系统之外编译.(见readdir(3))
我写了一个使用readdir查找目录的示例,使用d_type回stat退到d_type在编译时,DT_UNKNOWN和符号链接时不可用.
将d_type在返回结构给出了类型的数字。您不能直接打印它,因为当解释为 ASCII 时,使用的值不可打印(例如,它们是 4 表示目录,8 表示文件。)。
您可以将它们打印为这样的数字:
printf("%d ", dent->d_type)
Run Code Online (Sandbox Code Playgroud)
或者将它们与类似的常量进行比较,并从中DT_DIR构建一些有意义的输出,比如 char 类型:
if(dent->type == DT_DIR) type = 'd'
Run Code Online (Sandbox Code Playgroud)