如何判断 FILE* 是否指目录?
How to tell if FILE* is referring to a directory?
刚刚发现FILE*
不仅可以指代普通文件,还可以指代目录。如果是后者,fread
将失败,errno
设置为 21 (Is a directory)
。
可以测试最小重现here
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
int main() {
char const* sz = ".";
int fd = open(sz, O_RDONLY | O_NOFOLLOW); // all cleanup omitted for brevity
FILE* file = fdopen(fd, "rb");
// I would like to test in this line if it is a directory
char buffer[21];
int const n = fread(buffer, 1, 20, file);
if (0 < n) {
buffer[n] = 0;
printf(buffer);
} else {
printf("Error %d", errno); // 21 = Is a directory
}
}
尽早检测到我的 FILE*
引用目录而不尝试从中读取的正确方法是什么?
EDIT 排斥重复标志:
我想测试 FILE*
,而不是文件名。仅测试文件名然后稍后打开它是一种竞争条件。
假设您使用的是基于 POSIX 的系统,请使用 stat()
(如果您希望在调用 open()
之前使用 sz
中的文件名) 或 fstat()
(如果您希望在调用 open()
后使用描述符 fd
)从 OS 获取文件状态结构。名为 st_mode
的结构成员可以与 POSIX API S_ISDIR(st_mode)
一起使用来查看文件是否为目录。
假设一个类似于 POSIX 的环境,如果您只有文件流 (FILE *fp
),那么您可能只能使用 fileno()
and fstat()
:
#include <sys/stat.h>
struct stat sb;
if (fstat(fileno(fp), &sb) != 0)
…oops…
if (S_ISDIR(sb.st_mode))
…it is a directory…
else
…it is not a directory…
正在检查 fcntl.h man 页面:
header shall define the following symbolic constants as
file creation flags for use in the oflag value to open() and
openat(). The values shall be bitwise-distinct and shall be suitable
for use in #if preprocessing directives.
还有旗帜:
O_DIRECTORY Fail if not a directory.
刚刚发现FILE*
不仅可以指代普通文件,还可以指代目录。如果是后者,fread
将失败,errno
设置为 21 (Is a directory)
。
可以测试最小重现here
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
int main() {
char const* sz = ".";
int fd = open(sz, O_RDONLY | O_NOFOLLOW); // all cleanup omitted for brevity
FILE* file = fdopen(fd, "rb");
// I would like to test in this line if it is a directory
char buffer[21];
int const n = fread(buffer, 1, 20, file);
if (0 < n) {
buffer[n] = 0;
printf(buffer);
} else {
printf("Error %d", errno); // 21 = Is a directory
}
}
尽早检测到我的 FILE*
引用目录而不尝试从中读取的正确方法是什么?
EDIT 排斥重复标志:
我想测试 FILE*
,而不是文件名。仅测试文件名然后稍后打开它是一种竞争条件。
假设您使用的是基于 POSIX 的系统,请使用 stat()
(如果您希望在调用 open()
之前使用 sz
中的文件名) 或 fstat()
(如果您希望在调用 open()
后使用描述符 fd
)从 OS 获取文件状态结构。名为 st_mode
的结构成员可以与 POSIX API S_ISDIR(st_mode)
一起使用来查看文件是否为目录。
假设一个类似于 POSIX 的环境,如果您只有文件流 (FILE *fp
),那么您可能只能使用 fileno()
and fstat()
:
#include <sys/stat.h>
struct stat sb;
if (fstat(fileno(fp), &sb) != 0)
…oops…
if (S_ISDIR(sb.st_mode))
…it is a directory…
else
…it is not a directory…
正在检查 fcntl.h man 页面:
header shall define the following symbolic constants as file creation flags for use in the oflag value to open() and openat(). The values shall be bitwise-distinct and shall be suitable for use in #if preprocessing directives.
还有旗帜:
O_DIRECTORY Fail if not a directory.