纯C:用的fopen打开一个目录()
我打开一个文件,并检查其长度的节目。
I have a program which opens a file and checks its length.
FILE fd = fopen(argv[1], "rb");
fseek(fd, 0, SEEK_END);
size_t flen = ftell(fd);
if (flen == ((size_t)-1)) {
printf("%s is a directory.\n", argv[1]);
fclose(fd);
exit(1);
}
现在,至少在Linux下, fopen()函数
打开一个目录时返回一个有效的文件描述符。这导致在搜寻操作返回 1
(或者,如为size_t
是无符号,为0xFFFFFFFF
64位系统上)。
Now, at least under Linux, fopen()
returns a valid file descriptor when opening a directory. This results in the seek operation returning -1
(or, as size_t
is unsigned, 0xFFFFFFFF
on a 64-bit system).
不幸的是,在上述code的条件下( FLEN ==((为size_t)-1)
)没有赶上这种情况下,同样没有 FLEN == 0xFFFFFFFF的
。 的printf()
- 命令与%X
ORD %d个
作为格式字符串表明该比较的两侧应具有相同的值。
Unfortunately, the condition in the above code (flen == ((size_t)-1)
) does not catch that case, neither does flen == 0xFFFFFFFF
. printf()
-Commands with %x
ord %d
as format string show that both sides of the comparison should have the same value.
为什么用这种奇怪的方式比较循规蹈矩运营商,即使双方是同一类型的(为size_t
)?我使用GCC 4.8.1编译器为
Why does the comparison operator behave in such a strange way, even when both sides are of the same type (size_t
)? I am using gcc 4.8.1 as compiler.
目录不会出现在C99标准(或C2011的)存在。因此,通过定义,的fopen
-ing一个目录或者是具体执行或不确定的行为。
Directories do not exist in the C99 standard (or the C2011 one). So by definition, fopen
-ing a directory is either implementation specific or undefined behavior.
的fopen(3)可能失败(给人一种 NULL 结果)。 fseek的(3)也会失败(通过返回-1) 。然后你应该preferably检查错误号(3)或使用 PERROR(3)
fopen(3) can fail (giving a NULL
result). fseek(3) can also fail (by returning -1). And then you should preferably check errno(3) or use perror(3)
FTELL
是记录返回长
和 -1L
失败。在64位的Linux,这是 0xffffffffffffffff
。
ftell
is documented to return a long
, and -1L
on failure. On 64 bits Linux this is 0xffffffffffffffff
.
您code应该代替
FILE* fd = fopen(argv[1], "rb");
if (!fd)
{ perror(argv[1]); exit(EXIT_FAILURE); };
if (fseek(fd, 0, SEEK_END)<0)
{ perror("fseek"); exit(EXIT_FAILURE); };
long flen = ftell(fd);
if (flen == -1L)
{ perror("ftell"); exit(EXIT_FAILURE); };
BTW,在Linux / Debian的/ SID /带的libc-2.17和3.10.6内核AMD64,即codeS运行正常时,的argv [1]
是 / tmp目录
;惊喜地 FLEN
是 LONG_MAX
即 0x7fffffffffffffff
BTW, On Linux/Debian/Sid/AMD64 with libc-2.17 and 3.10.6 kernel, that codes runs ok when argv[1]
is /tmp
; surprizingly, flen
is LONG_MAX
i.e. 0x7fffffffffffffff