检查Unix中是否存在一个目录(系统调用)

时间:2020-12-05 00:03:22

I am not able to find a solution to my problem online.

我在网上找不到解决我问题的办法。

I would like to call a function in Unix, pass in the path of a directory, and know if it exists. opendir() returns an error if a directory does not exist, but my goal is not to actually open, check the error, close it if no error, but rather just check if a file is a directory or not.

我想在Unix中调用一个函数,传入一个目录的路径,并知道它是否存在。如果目录不存在,opendir()返回一个错误,但是我的目标不是打开,检查错误,如果没有错误,关闭它,而是检查文件是否为目录。

Is there any convenient way to do that please?

请问有什么方便的办法吗?

7 个解决方案

#1


90  

There are two relevant functions on POSIX systems: stat() and lstat(). These are used to find out whether a pathname refers to an actual object that you have permission to access, and if so, the data returned tells you what type of object it is. The difference between stat() and lstat() is that if the name you give is a symbolic link, stat() follows the symbolic link (or links if they are chained together) and reports on the object at the end of the chain of links, whereas lstat() reports on the symbolic link itself.

POSIX系统有两个相关函数:stat()和lstat()。这些用于查明路径名是否指向您拥有访问权限的实际对象,如果是,返回的数据将告诉您它是什么类型的对象。stat()和lstat()之间的区别在于,如果您给出的名称是一个符号链接,那么stat()会跟随符号链接(或者链接在一起的链接),并在链接链的末尾报告对象,而lstat()会报告符号链接本身。

#include <sys/stat.h>

struct stat sb;

if (stat(pathname, &sb) == 0 && S_ISDIR(sb.st_mode))
{
    ...it is a directory...
}

If the function indicates it was successful, you use the S_ISDIR() macro from <sys/stat.h> to determine whether the file is actually a directory.

如果函数表明它是成功的,则使用 来确定文件是否实际上是一个目录。

You can also check for other file types using other S_IS* macros:

您还可以使用其他S_IS*宏检查其他文件类型:

  • S_ISDIR — directory
  • S_ISDIR -目录
  • S_ISREG — regular file
  • S_ISREG——常规文件
  • S_ISCHR — character device
  • S_ISCHR -字符设备
  • S_ISBLK — block device
  • S_ISBLK——块设备
  • S_ISFIFO — FIFO
  • S_ISFIFO - FIFO
  • S_ISLNK — symbolic link
  • S_ISLNK——符号链接
  • S_ISSOCK — socket
  • S_ISSOCK——套接字

(Some systems provide a few other file types too; S_ISDOOR is available on Solaris, for example.)

(有些系统也提供一些其他的文件类型;例如,在Solaris上可以使用S_ISDOOR。

#2


5  

You can make use of the stat system call by passing it the name of the directory as the first argument. If the directory exists a 0 is returned else -1 is returned and errno will be set to ENOENT

可以通过将目录的名称作为第一个参数传递给stat系统调用。如果目录存在,则返回0,否则返回-1,并将errno设置为ENOENT

EDIT:

编辑:

If the return value is 0 you would need an additional check to ensure that the argument is actually a directory and not a file/symlink/char special file/blk special file/FIFO file. You can make use of the st_mode field of the stat structure for this.

如果返回值为0,则需要进行额外检查,以确保参数实际上是一个目录,而不是文件/符号链接/char特殊文件/blk特殊文件/FIFO文件。您可以为此使用stat结构的st_mode字段。

#3


3  

You could use test -d

你可以用测试-d

#4


2  

If you're talking about from a shell, there's a good SO answer here. To summarize that answer:

如果你说的是壳层,这里有个很好的答案。总结,回答:

if [ -d "$DIRECTORY" ]; then
    # Control will enter here if $DIRECTORY exists
fi

If you're talking from inside a C program, you can use stat():

如果您在C程序内部进行对话,可以使用stat():

{
    struct stat st;
    if(stat("/tmp",&st) == 0)
        printf(" /tmp is present\n");
}

#5


1  

If you don't really care about type of this filesystem object, access(name, F_OK) checks for exsistence of something with this name. If you need to be sure this is directory, use stat() and check type with S_ISDIR() macro.

如果您并不真正关心这个文件系统对象的类型,那么访问(name, F_OK)将检查具有这个名称的内容的存在性。如果需要确保这是目录,请使用stat()并使用S_ISDIR()宏检查类型。

#6


1  

Tested and working fine:

测试和工作正常:

int file_exist (char *filename)
{
    char s[200];
    sprintf(s, "test -e %s", filename);
    if (system(s) == 0){
        return 1;
    }else{
        return 0;
    }
}

#7


0  

I think the function stat may do what you want (I havent test it for directories). In C++, you can also use the boost::filesystem library.

我认为函数stat可以做您想做的事情(我还没有对目录进行测试)。在c++中,您还可以使用boost:::文件系统库。

#1


90  

There are two relevant functions on POSIX systems: stat() and lstat(). These are used to find out whether a pathname refers to an actual object that you have permission to access, and if so, the data returned tells you what type of object it is. The difference between stat() and lstat() is that if the name you give is a symbolic link, stat() follows the symbolic link (or links if they are chained together) and reports on the object at the end of the chain of links, whereas lstat() reports on the symbolic link itself.

POSIX系统有两个相关函数:stat()和lstat()。这些用于查明路径名是否指向您拥有访问权限的实际对象,如果是,返回的数据将告诉您它是什么类型的对象。stat()和lstat()之间的区别在于,如果您给出的名称是一个符号链接,那么stat()会跟随符号链接(或者链接在一起的链接),并在链接链的末尾报告对象,而lstat()会报告符号链接本身。

#include <sys/stat.h>

struct stat sb;

if (stat(pathname, &sb) == 0 && S_ISDIR(sb.st_mode))
{
    ...it is a directory...
}

If the function indicates it was successful, you use the S_ISDIR() macro from <sys/stat.h> to determine whether the file is actually a directory.

如果函数表明它是成功的,则使用 来确定文件是否实际上是一个目录。

You can also check for other file types using other S_IS* macros:

您还可以使用其他S_IS*宏检查其他文件类型:

  • S_ISDIR — directory
  • S_ISDIR -目录
  • S_ISREG — regular file
  • S_ISREG——常规文件
  • S_ISCHR — character device
  • S_ISCHR -字符设备
  • S_ISBLK — block device
  • S_ISBLK——块设备
  • S_ISFIFO — FIFO
  • S_ISFIFO - FIFO
  • S_ISLNK — symbolic link
  • S_ISLNK——符号链接
  • S_ISSOCK — socket
  • S_ISSOCK——套接字

(Some systems provide a few other file types too; S_ISDOOR is available on Solaris, for example.)

(有些系统也提供一些其他的文件类型;例如,在Solaris上可以使用S_ISDOOR。

#2


5  

You can make use of the stat system call by passing it the name of the directory as the first argument. If the directory exists a 0 is returned else -1 is returned and errno will be set to ENOENT

可以通过将目录的名称作为第一个参数传递给stat系统调用。如果目录存在,则返回0,否则返回-1,并将errno设置为ENOENT

EDIT:

编辑:

If the return value is 0 you would need an additional check to ensure that the argument is actually a directory and not a file/symlink/char special file/blk special file/FIFO file. You can make use of the st_mode field of the stat structure for this.

如果返回值为0,则需要进行额外检查,以确保参数实际上是一个目录,而不是文件/符号链接/char特殊文件/blk特殊文件/FIFO文件。您可以为此使用stat结构的st_mode字段。

#3


3  

You could use test -d

你可以用测试-d

#4


2  

If you're talking about from a shell, there's a good SO answer here. To summarize that answer:

如果你说的是壳层,这里有个很好的答案。总结,回答:

if [ -d "$DIRECTORY" ]; then
    # Control will enter here if $DIRECTORY exists
fi

If you're talking from inside a C program, you can use stat():

如果您在C程序内部进行对话,可以使用stat():

{
    struct stat st;
    if(stat("/tmp",&st) == 0)
        printf(" /tmp is present\n");
}

#5


1  

If you don't really care about type of this filesystem object, access(name, F_OK) checks for exsistence of something with this name. If you need to be sure this is directory, use stat() and check type with S_ISDIR() macro.

如果您并不真正关心这个文件系统对象的类型,那么访问(name, F_OK)将检查具有这个名称的内容的存在性。如果需要确保这是目录,请使用stat()并使用S_ISDIR()宏检查类型。

#6


1  

Tested and working fine:

测试和工作正常:

int file_exist (char *filename)
{
    char s[200];
    sprintf(s, "test -e %s", filename);
    if (system(s) == 0){
        return 1;
    }else{
        return 0;
    }
}

#7


0  

I think the function stat may do what you want (I havent test it for directories). In C++, you can also use the boost::filesystem library.

我认为函数stat可以做您想做的事情(我还没有对目录进行测试)。在c++中,您还可以使用boost:::文件系统库。