【问题标题】:Checking whether a file can be opened using portable C检查是否可以使用便携式 C 打开文件
【发布时间】:2009-03-16 14:47:06
【问题描述】:

我想快速检查一个文件是否可以打开。它应该用可移植的 C 语言编写,或者至少可以在 Win32 和 POSIX 系统上工作。 #ifdefs 是可以接受的。

我试图避免这种情况:

int openable(const char*filename) {
    FILE *f = fopen(filename,"r");
    if (!f)
        return 0; /* openable */
    fclose(f);
    return 1; /* not openable */
}

据我所知,stat() 最简单的形式可用于检查文件是否存在,但不能用于检查它是否实际可打开。

【问题讨论】:

  • 你的代码或多或少是 ANSI 的方式,这没有错。

标签: c file-io


【解决方案1】:

POSIX 标准解决方案是@987654321@(),在 Windows 运行时中也是 @987654322@

我猜它比fopen()+fclose() 稍微好一点,因为:

  • 这是测试文件访问权限问题的众所周知的标准解决方案
  • 它很可能更快,内存开销更少

当然,它与任何其他进行此类测试的方式一样容易受到竞争条件的影响。在某种程度上,知道文件是否可供读取的唯一安全方法是打开它并尝试读取,而不是在两者之间关闭它。当然,即便如此,您仍然需要注意“意外的”EOF。 I/O 很难。

【讨论】:

  • 注意 access() 可能会告诉您无法访问 setuid 程序中的文件,即使 fopen() 可以正常打开的文件:gnu.org/software/libtool/manual/libc/Testing-File-Access.html
  • 谢谢,放松,不知道 access(),这就是我要找的。比赛条件在我所做的事情中并不是真正的问题:) dmityugov,非常感谢您的评论,我会小心的!
  • 我认为原始解决方案实际上可能比 access() 更可取。 access() 可能会比 fopen()/fclose() 稍微快一点,但是在各种边缘情况(setuid、ACL 或竞态条件)中,access() 实际上不会告诉您是否可以读取文件。
【解决方案2】:

在您知道一个文件是“可打开的”之前,您需要检查许多因素,而试图以跨平台的方式检查它们是愚蠢的。

我认为你现在做的事情更简单更安全。 但是请记住,仅仅因为一个文件是“可打开的”现在并不意味着它仍然会在您真正打开它时仍然存在。在此期间没有什么能阻止它发生变化。

【讨论】:

  • 我的评论来自迈克尔的回应 :)
【解决方案3】:

我认为您所拥有的可能与您将获得的一样好(尽管您的 cmets 与应有的相反)。有很多因素会阻止文件打开:权限、保持打开状态的其他因素、资源不足等。

要准确地完成所有这些检查,你不妨打开这个东西。

但是,另请注意,在大多数系统上,您返回的内容可能是对调用者的谎言 - 当您向调用者返回有关文件是否可以打开的指示时,系统的状态可能会改变(例如,保持文件打开的东西可能会关闭它)。因此,应用程序要知道它们是否可以打开和使用文件的唯一真正有效的方法就是打开和使用文件(并处理任何故障)。

换句话说,如果您将“true”返回给调用者,他们可能会尝试打开文件,但仍可能失败。

【讨论】:

  • 谢谢,但这主要是为了决定加载哪个配置文件,而不需要对代码进行重大重组。幸运的是,这是服务器启动期间的一次性操作,因此不太可能失败。
  • 请注意,即使您擅长通过 'stat()' 检查文件的权限,例如,如果有 ACL 在使用中,您将无法确定文件是否可以打开,除非你也找那些。
猜你喜欢
  • 2012-09-28
  • 2022-10-30
  • 2013-10-30
  • 2011-03-27
  • 2013-08-08
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多