C++ 带结构指令的系统/统计S_ISDIR(m)

C++ 带结构指令的系统/统计S_ISDIR(m),c++,c,systems-programming,C++,C,Systems Programming,我想检查文件是目录、链接还是普通文件。我循环遍历目录,并将每个文件保存为struct dirent*。我尝试将d_ino传递到S_ISDIR(m),S_ISLINK(m),或S_ISREG(m),无论文件是什么,我都不会得到肯定的结果。因此,我的问题是:如何将S_-ISDIR(m)与struct-dirent一起使用?S_-ISDIR(m),S_-ISLINK(m)用于struct-stat.st_模式,而不是struct-dirent。例如: struct stat sb; ... stat

我想检查文件是目录、链接还是普通文件。我循环遍历目录,并将每个文件保存为
struct dirent*
。我尝试将
d_ino
传递到
S_ISDIR(m)
S_ISLINK(m)
,或
S_ISREG(m)
,无论文件是什么,我都不会得到肯定的结果。因此,我的问题是:如何将
S_-ISDIR(m)
struct-dirent
一起使用?

S_-ISDIR(m),S_-ISLINK(m)用于
struct-stat.st_模式,而不是
struct-dirent
。例如:

struct stat sb;
...
stat ("/", &sb);
printf ("%d", S_ISDIR (sb.st_mode));

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

但是,并非所有实现都具有
d_type
成员的有效数据,因此您可能需要对每个文件调用或以确定其文件类型(如果您对符号链接感兴趣,请使用
lstat
,如果您对符号链接的目标感兴趣,请使用
stat
)然后使用
S\u IS***
宏检查
st\u模式
成员

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

// 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);
struct dirent someDirEnt;
... //stuff get it filled out
if(someDirEnt.d_type==DT_LNK)
...//whatever you link

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

// 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);
struct dirent someDirEnt;
... //stuff get it filled out
if(someDirEnt.d_type==DT_LNK)
...//whatever you link
具体而言,d_类型成员可包含:


S\u IS*
宏不能直接与d\u类型一起使用。在我见过的大多数系统中,它们彼此之间的偏移量为12位。您必须使用
IFTODT
DTTOIF
宏(非标准,或者直接与
DT.*
宏值进行比较。Solaris上没有“d_type”字段;-)顺便说一句:这些东西甚至可以在使用Cygwin的Windows上使用(在我的例子中是NetBeans)。