我正在制作一个在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 \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;
}
由于某种原因,dent->d_type
未显示文件类型。我不确定该做什么,有什么建议吗?
答案 0 :(得分:19)
d_type
是一种速度优化,可以在lstat(2)
次来电时保存。{/ p>
正如readdir
(3) man page指出的那样,并非所有文件系统都在d_type
字段中返回实际信息(通常是因为需要额外的磁盘搜索来读取inode,如果你是XFS的情况没有使用mkfs.xfs -n ftype=1
(-m crc=1
暗示,这还不是默认设置)。总是设置DT_UNKNOWN
的文件系统在现实生活中很常见,而不是你可以忽略的东西。 XFS不是唯一的例子。
如果仅使用d_type==DT_UNKNOWN
,如果单独的文件名不足以决定它是无趣的,那么您总是需要使用lstat
(2)的代码。 (对于某些呼叫者来说就是这种情况,例如find -name
或者像*.c
那样扩展整体,这就是为什么readdir
不会产生填充它的开销的原因。额外的磁盘读取。)
Linux getdents(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)
)
我为finding directories with readdir 编写了示例,当d_type在编译时不可用时使用d_type
并回退到stat
。 #39; s DT_UNKNOWN,以及符号链接。
答案 1 :(得分:4)
返回结构中的d_type
给出了该类型的数字。您无法直接打印,因为在解释为ASCII时,所使用的值不可打印(例如,dirs为4,文件为8。)
你可以将它们打印成这样的数字:
printf("%d ", dent->d_type)
或者将它们与DT_DIR
之类的常量进行比较,并从中构造一些有意义的输出,如char类型:
if(dent->type == DT_DIR) type = 'd'
答案 2 :(得分:2)
将d_type
打印为如下所示的整数:
printf("%d ", dent->d_type);
你会看到有意义的价值观。
答案 3 :(得分:0)
我能够在ubuntu上使用d_type:
switch (readDir->d_type)
{
case DT_DIR:
printf("Dir: %s\n", readDir->d_name);
break;
case DT_REG:
printf("File: %s\n", readDir->d_name);
break;
default:
printf("Other: %s\n", readDir->d_name);
}
条目类型的列表可以在dirent.h中找到(对于ubuntu以外的其他操作系统可能有所不同):
dirent.h
#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