3

我想检查文件是目录、链接还是普通文件。我遍历目录并将每个文件保存为struct dirent *. 我尝试传递d_inoS_ISDIR(m)S_ISLINK(m)S_ISREG(m)无论文件如何,我都不会得到肯定的结果。所以我的问题是:我如何使用S_ISDIR(m)with struct dirent

4

3 回答 3

9

当您使用 读取目录readdir(3)时,文件类型存储在您收到d_type的每个成员变量中,而不是成员中。您很少会关心 inode 编号。struct direntd_ino

然而,并不是所有的实现都会为d_type成员提供有效的数据,因此您可能需要在每个文件上调用stat(3)orlstat(3)来确定其文件类型(lstat如果您对符号链接感兴趣,请使用,或者stat如果您对符号链接),然后使用宏检查st_mode成员。S_IS***

典型的目录迭代可能如下所示:

// Error checking omitted for expository purposes
DIR *dir = opendir(dir_to_read);
struct dirent *entry;

while((entry = readdir(dir)) != NULL)
{
    struct stat st;
    char filename[512];
    snprintf(filename, sizeof(filename), "%s/%s", dir_to_read, entry->d_name);
    lstat(filename, &st);

    if(S_ISDIR(st.st_mode))
    {
        // This directory entry is another directory
    }
    else if(S_ISLINK(st.st_mode))
    {
        // This entry is a symbolic link
    }
    else if(S_ISREG(st.st_mode))
    {
        // This entry is a regular file
    }
    // etc.
}

closedir(dir);
于 2012-04-29T21:40:26.570 回答
0

S_ISDIR(m), S_ISLINK(m) 用于对抗struct stat.st_mode,而不是struct dirent。例如:

struct stat sb;
...
stat ("/", &sb);
printf ("%d", S_ISDIR (sb.st_mode));
于 2012-04-29T21:28:49.647 回答
0

不幸的是,如上所述,您不能将 S_IS* 宏与 struct dirent 成员一起使用。但是,您不需要,因为成员 d_type 已经为您提供了该信息。您可以像这样直接测试它:

struct dirent someDirEnt;
... //stuff get it filled out
if(someDirEnt.d_type==DT_LNK)
...//whatever you link

特别是 d_type 成员可能包含:

   DT_BLK      This is a block device.
   DT_CHR      This is a character device.
   DT_DIR      This is a directory.
   DT_FIFO     This is a named pipe (FIFO).
   DT_LNK      This is a symbolic link.
   DT_REG      This is a regular file.
   DT_SOCK     This is a UNIX domain socket.
   DT_UNKNOWN  The file type is unknown.
于 2013-01-30T15:53:53.297 回答