当前位置: 首页 > 面试题库 >

pure C:使用fopen()打开目录

赫连骏
2023-03-14
问题内容

我有一个程序来打开文件并检查其长度。

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无符号,在64位系统上为0xFFFFFFFFFFFFFFFF=
2 64 -1)。

不幸的是,上面的代码(flen == ((size_t)-1))中的条件无法解决这种情况,flen == 0xFFFFFFFF(EDIT:应该是0xFFFFFFFFFFFFFFFF)也没有。printf()-将%xord
%d作为格式字符串的命令显示比较的两面应具有相同的值。

为什么即使两边都是相同类型(size_t),比较运算符的行为也是如此奇怪?我正在使用gcc 4.8.1作为编译器。


问题答案:

目录在C99标准(或C2011标准)中不存在。因此,根据定义,fopen-ing目录是实现特定的行为或未定义的行为。

fopen(3)可能会失败(给出NULL结果)。fseek(3)也可能失败(返回-1)。然后您最好检查errno(3)或使用perror(3)

ftell是记录在案,以返回long,和-1L失败。在64位Linux上,这是0xffffffffffffffff

您的代码应改为

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); };

顺便说一句,在具有libc-2.17和3.10.6内核的Linux / Debian / Sid / AMD64上,当argv[1]is
时,代码可以正常运行/tmp;惊喜地,flenLONG_MAX0x7fffffffffffffff

顺便说一句,在Linux上,目录是文件的特例。在文件路径上(以及在文件描述符(可能是通过some从fileno(3)获取)上)使用stat(2)来了解有关某个文件的更多元数据,包括其“类型”(通过其模式)。您希望opendir(3),readdir(3)和closedir(3)对目录内容进行操作。另请参见inode(7)。fstatFILE*



 类似资料:
  • 我正在按照教程将图片从android上传到服务器,我在服务器端使用php,这是代码: 当我尝试运行时,它会向我显示以下错误: fopen(uploadedimages/):无法打开流:中没有这样的文件或目录... fwrite()期望参数1为资源,布尔值在…fclose()中给定期望参数1是资源,布尔函数在…中给定。。。 我对php非常陌生,所以请帮助我(我从互联网上找到了一些答案,但它不适合我)

  • 我正在使用Codeignighter,FPDF和FPDI来修改要通过电子邮件发送给客户的PDF。 使用FPDI给出的基本示例,我可以让我的代码在localhost上完美工作(独立的php文件,没有代码签名器),但是当我将相同的文件放到服务器上时,我会收到以下警告和错误。 严重性:警告 消息:fopen(PDF.pdf):无法打开流:没有这样的文件或目录 文件名: pdfParser/StreamR

  • 在我的代码中,我创建了一个名为的文件。我后来想打开它并从中读取内容,但我得到的错误

  • 打开和关闭目录 打开和关闭目录 源码/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * *//* * 程序清单:打开目录 * * 程序会创建一个操作文件的函数并导出到msh命令列表

  • 问题内容: 您是否有想要使用的任何原因(除了语法原因之外) 要么 代替 在Linux环境中使用C时? 问题答案: 首先,没有特别好的理由去使用if 是一个选项,而另一个是可能的选择。如果您要使用,则不应该首先使用该文件。因此,将其包括在该列表中是不正确且令人困惑的,因为它与其他列表不太相似。现在,我将继续忽略它,因为此处的重要区别在于C标准和OS特定的文件描述符之间。 使用而不是的主要原因有四个。

  • 我是PHP新手。我计划根据用户输入创建文件夹、子文件夹。 文件夹和子文件夹已成功创建。 最后我尝试创建一个文件,它显示以下错误。 fopen(upload/llocalhost/hrms):无法打开流:在C:\xamp\htdocs\ssspider\index中的权限被拒绝。php第205行 我的代码是: 请帮我找出我的问题? 编辑:谢谢。我出错了。以前我没有提到文件名。现在工作正常。谢谢