C 检查文件是目录还是仅仅是文件

C 检查文件是目录还是仅仅是文件,c,posix,C,Posix,我正在写一个程序来检查某个东西是文件还是目录。还有比这更好的方法吗 #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <errno.h> int isFile(const char* name) { DIR* directory = opendir(name); if(directory != NULL) { clos

我正在写一个程序来检查某个东西是文件还是目录。还有比这更好的方法吗

#include <stdio.h>

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>

int isFile(const char* name)
{
    DIR* directory = opendir(name);

    if(directory != NULL)
    {
     closedir(directory);
     return 0;
    }

    if(errno == ENOTDIR)
    {
     return 1;
    }

    return -1;
}

int main(void)
{
    const char* file = "./testFile";
    const char* directory = "./";

    printf("Is %s a file? %s.\n", file,
     ((isFile(file) == 1) ? "Yes" : "No"));

    printf("Is %s a directory? %s.\n", directory,
     ((isFile(directory) == 0) ? "Yes" : "No"));

    return 0;
}
#包括
#包括
#包括
#包括
int isFile(常量字符*名称)
{
DIR*directory=opendir(名称);
if(目录!=NULL)
{
closedir(目录);
返回0;
}
如果(errno==ENOTDIR)
{
返回1;
}
返回-1;
}
内部主(空)
{
const char*file=“./testFile”;
常量字符*目录=“../”;
printf(“是%s文件吗?%s.\n”,文件,
((isFile(file)==1)?“是”:“否”);
printf(“是%s目录吗?%s.\n”,目录,
((isFile(directory)==0)?“是”:“否”);
返回0;
}

是的,有更好的。检查
stat
fstat
功能

使用
S_ISDIR
宏:

int isDirectory(const char *path) {
   struct stat statbuf;
   if (stat(path, &statbuf) != 0)
       return 0;
   return S_ISDIR(statbuf.st_mode);
}
您可以调用函数并在结构的
st\u mode
字段上使用
S\u ISREG()
宏,以确定路径是否指向常规文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int is_regular_file(const char *path)
{
    struct stat path_stat;
    stat(path, &path_stat);
    return S_ISREG(path_stat.st_mode);
}
#包括
#包括
#包括
int是常规文件(const char*path)
{
结构状态路径\ u状态;
统计(路径和路径统计);
返回S_ISREG(路径统计st_模式);
}

请注意,除了常规和目录之外,还有其他文件类型,如设备、管道、符号链接、套接字等。您可能需要考虑这些文件类型。

通常,您希望使用结果以原子方式执行此检查,因此没有用。相反,先将文件只读并使用。如果它是一个目录,那么您可以使用 阅读它。或者你可以尝试打开它开始写,如果它是一个目录,打开就会失败。一些系统(POSIX 2008,Linux)也有一个
O_目录
扩展到
open
,如果名称不是目录,则调用会失败


如果你想要一个目录,你的方法也是很好的,但是你不应该在之后关闭它;你应该继续使用它。

你忘记了用信息填充
statbuf
结构。这样做很好,stat函数会填充信息本身。理想情况下,代码会检查
stat
是否有效:
如果(stat(path,&statbuf)!=0)返回0--因为不存在的对象不是目录,如果您没有权限
stat()
它,它也可能不存在(即使报告的错误与权限有关)。@JonathanLeffler您完全正确,更新了代码。在考虑符号链接情况时,请使用lstat()而不是stat()因为它不遵循符号链接。至少在上有一个很好的讨论,其中讨论了
stat()
lstat()
,并概述了完整的POSIX文件类型集。我很想把这个问题复制到那个问题上。代码也应该检查
stat()
的结果,并适当地处理错误。@Jonathan,这个答案确实比我的答案更完整,并且比我的答案早三个月发布,也就是五年前。而且我自己的答案也不会消失。我看到你在
[c]
标签中挥舞着Mjölnir,所以感谢你在单方面行动之前发表评论。然而,你最终是对的。不用担心,做你必须做的:)这对我来说在osx上不起作用…@vodish,也许
stat()
对你来说失败了?副本中的代码怎么样,对你有用吗?