c - fopen 打开目录?

c - fopen opening directories?

我正在使用 fopen() 来确定我打开的是文件还是目录,如下所示:

FILE *f;

f = fopen(path, "r");

if (f != NULL){

// found file

}

else {

// found a directory

}

路径目前是指向目录的路径,而不是文件,它看起来像这样:

/home/me/Desktop/newfolder

但是,当我 运行 代码时,它说它找到了一个文件,即使它指向一个文件夹,因此它应该 return NULL 指针,还是不是?

我正在研究 Ubuntu。

先试试这个:

#include <dirent.h>

DIR* dir = opendir(path);
if (dir)
{
    /* Directory exists. Do stuff. */
    closedir(dir);
}
if(errno == ENOTDIR)
{   
    /* Exists but is not a directory */
}

C 标准没有提及任何关于 fopening 目录的内容。

但是 http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html 说了以下内容(强调我的):

The fopen() function will fail if:
[…]
[EISDIR] The named file is a directory and mode requires write access.

因此,如果您将 fopen(path, "r") 更改为例如fopen(path, "r+") 那么如果 path 指的是一个目录,它应该会失败:

bool isDirectory(const char* path) {
    FILE *f = fopen(path, "r+");
    if (f) {
        fclose(f);
        return false;
    }
    return errno == EISDIR;
}

先显示代码

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

int is_reg_file(const char *path)
{
    struct stat statbuf;
    stat(path, &statbuf);
    // test for a regular file
    if (S_ISREG(statbuf.st_mode))
        return 1;
    return 0;
}

int is_dir(const char *path)
{
    struct stat statbuf;
    stat(path, &statbuf);
    if (S_ISDIR(statbuf.st_mode))
        return 1;
    return 0;
}

stat 结构体定义如下,详见stat(2) 手册

struct stat {
    dev_t     st_dev;         /* ID of device containing file */
    ino_t     st_ino;         /* Inode number */
    mode_t    st_mode;        /* File type and mode */
    nlink_t   st_nlink;       /* Number of hard links */
    uid_t     st_uid;         /* User ID of owner */
    gid_t     st_gid;         /* Group ID of owner */
    dev_t     st_rdev;        /* Device ID (if special file) */
    off_t     st_size;        /* Total size, in bytes */
    blksize_t st_blksize;     /* Block size for filesystem I/O */
    blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
    ...
};

st_mode中定义的文件类型可以在inode(7)手册中找到,还有一些宏。

  POSIX  refers  to the stat.st_mode bits corresponding to the mask S_IFMT (see below)
       as the file type, the 12 bits corresponding to the mask 07777 as the file mode  bits
       and the least significant 9 bits (0777) as the file permission bits.

       The following mask values are defined for the file type:

           S_IFMT     0170000   bit mask for the file type bit field

           S_IFSOCK   0140000   socket
           S_IFLNK    0120000   symbolic link
           S_IFREG    0100000   regular file
           S_IFBLK    0060000   block device
           S_IFDIR    0040000   directory
           S_IFCHR    0020000   character device
           S_IFIFO    0010000   FIFO