检测文件类型(常规文件,目录,符号链接等)

时间:2014-08-30 20:34:08

标签: c

我正在尝试使用stat(2)来确定argv [i]是否是常规文件,目录或符号链接。 stat(2)手册页中有两件我不理解的内容:

  1. stat(2)采取的第二个论点是什么(即buf arg)

     int stat(const char *path, struct stat *buf);
    
  2. 如何使用返回值来确定它是reg文件,目录还是sym链接?

1 个答案:

答案 0 :(得分:4)

要回答第一个问题,您可以取消引用stat结构的实例,并将该解除引用的值传递给stat()以填充实例的字段值:

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

/* ... */

struct stat foo;
const char *path = "/a/b/c";

/* test the result of stat() to make sure it ran correctly */

if (stat(path, &foo) != 0) { 
    fprintf(stderr, "something went wrong with stat()\n"); 
    exit(EXIT_FAILURE); 
}

/* now do stuff with foo; e.g. from docs: */

switch (foo.st_mode & S_IFMT) {
    case S_IFBLK:  printf("block device\n");            break;
    case S_IFCHR:  printf("character device\n");        break;
    case S_IFDIR:  printf("directory\n");               break;
    case S_IFIFO:  printf("FIFO/pipe\n");               break;
    case S_IFLNK:  printf("symlink\n");                 break;
    case S_IFREG:  printf("regular file\n");            break;
    case S_IFSOCK: printf("socket\n");                  break;
    default:       printf("unknown?\n");                break;
}

要回答第二个问题,请链接到以下文档:

The following POSIX macros are defined to check 
the file type using the st_mode field:

S_ISREG(m) - is it a regular file?
S_ISDIR(m) - directory?
S_ISCHR(m) - character device?
S_ISBLK(m) - block device?
S_ISFIFO(m) - FIFO (named pipe)?
S_ISLNK(m) - symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(m) - socket? (Not in POSIX.1-1996.)

如果st_mode成功,则stat()字段会被填充,因此您可以将该结果传递给上面列出的宏:

if (S_ISREG(foo.st_mode)) { 
    fprintf(stderr, "whatever foo points to is a regular file\n"); 
}
else {
    fprintf(stderr, "whatever foo points to is something else\n"); 
}

您应首先测试stat()的结果,以确保您在st_mode和其他字段中具有可用值。再次参考文档,它实际上编写得非常好,或者查看上面的代码片段。