问题描述
我正在制作一个程序,该程序在Linux shell中运行,并接受一个参数(目录),并显示目录中的所有文件及其类型.
I am making a program which is run in a Linux shell, and accepts an argument (a directory), and displays all the files in the directory, along with their type.
输出应如下所示:
<< ./Program testDirectory
Dir directory1
lnk linkprogram.c
reg file.txt
如果不做任何参数,它将使用当前目录.这是我的代码:
If no argument is made, it uses the current directory. Here is my code:
#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
没有显示文件类型.我不太确定该怎么办,有什么建议吗?
For some reason dent->d_type
is not displaying the type of file. I'm not really sure what to do, any suggestions?
推荐答案
d_type
是一种速度优化,可在受支持的情况下保存在lstat(2)
调用中.
d_type
is a speed optimization to save on lstat(2)
calls, when it's supported.
readdir
(3)手册页指出,并非所有文件系统在d_type
字段中返回真实信息(通常是因为需要额外的磁盘搜索来读取inode,如果不使用mkfs.xfs -n ftype=1
,则是XFS的情况(由-m crc=1
表示,这还不是默认情况下,总是设置为DT_UNKNOWN
的文件系统在现实生活中很常见,并不是您可以忽略的东西.XFS并不是唯一的例子.
As the readdir
(3) man page points out, not all filesystems return real info in the d_type
field (typically because it would take an extra disk seek to read the inode, as is the case for XFS if you didn't use mkfs.xfs -n ftype=1
(implied by -m crc=1
which is not yet the default). Filesystems that always set DT_UNKNOWN
are common in real life, and not something that you can ignore. XFS is not the only example.
您始终需要使用 lstat
(2)的代码如果是d_type==DT_UNKNOWN
,则仅凭文件名不足以决定它没有意思. (对于某些调用程序,例如find -name
或扩展的glob这样的*.c
,就是这种情况,这就是为什么readdir
不需要额外读取磁盘就不会产生填充它的开销的原因.)
You always need code that will fall back to using lstat
(2) if d_type==DT_UNKNOWN
, if the filename alone isn't enough to decide it's uninteresting. (This is the case for some callers, like find -name
or expanding globs like *.c
, which is why readdir
doesn't incur the overhead of filling it in if it would take an extra disk read.)
Linux getdents(2)
手册页上有一个示例程序,它可以完成您的工作重新尝试做,包括一个链接的三元运算符块,将d_type
字段解码为文本字符串. (正如其他答案所指出的那样,您的错误是将其作为字符打印出来,而不是与DT_REG
,DT_DIR
等进行比较).
The Linux getdents(2)
man page has an example program that does what you're trying to do, including a chained-ternary-operator block to decode the d_type
field into text strings. (As the other answers point out, your mistake is printing it out as an character, rather than comparing it against DT_REG
, DT_DIR
, etc.)
无论如何,其他答案大多涵盖了所有内容,但是错过了需要后备的关键细节,因为d_type == DT_UNKNOWN
(在Linux上为0.d_type
是填充字节,直到Linux 2.6.4).
Anyway, the other answers mostly covered things, but missed the critical detail that you NEED a fallback for the case when d_type == DT_UNKNOWN
(0 on Linux. d_type
is stored in what used to be a padding byte, until Linux 2.6.4).
要便于移植,您的代码需要检查struct dirent
甚至是否有d_type
字段(如果使用的话),或者您的代码甚至不编译在GNU和BSD系统之外. (请参见readdir(3)
)
To be portable, your code needs to check that struct dirent
even HAS a d_type
field, if you use it, or your code won't even compile outside of GNU and BSD systems. (see readdir(3)
)
我写了 使用readdir查找目录的示例 ,并使用了d_type
当d_type在编译时不可用,为DT_UNKNOWN时以及对于符号链接时,回退到stat
.
I wrote an example for finding directories with readdir, using d_type
with a fallback to stat
when d_type isn't available at compile time, when it's DT_UNKNOWN, and for symlinks.
这篇关于检查目录. readdir返回的条目是目录,链接或文件. dent-> d_type没有显示类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!