Stackoverflow热门问题(九)-C确定文件存在的最好方式是什么?

stackoverflow热门问题目录

如有翻译问题欢迎评论指出,谢谢。

C确定文件存在的最好方式是什么?

  • Dave Marshall asked:
    • 有什么比下面更好的途径来尝试打开文件吗?
    • int exists(const char *fname)
    • {
    • FILE *file;
    • if ((file = fopen(fname, "r")))
    • {
    • fclose(file);
    • return 1;
    • }
    • return 0;
    • }
  • Answers:
    • Graeme Perrow – vote: 670
      • 试试access()函数,头文件是unist.h。用它来将你的函数改为:
      • if( access( fname, F_OK ) == 0 ) {
      • // file exists
      • } else {
      • // file doesn't exist
      • }
      • 使用R_OK, W_OK, X_OK来代替F_OK,可以在确定文件存在的前提上确定文件的读、写、执行权限,并且能够使用 或 来同时使用它们(例如用R_OK|W_OK确定读和写权限)
      • 更新:注意,在Windows中,不要用W_OK来测试写权限,因为access函数不会将DACLs考虑在内。access( fname, W_OK) 可能返回0(表成功),因为文件不存在只读属性设置,但你仍然没有该文件的写权限。
    • codebunny – vote: 127
      • stat
      • #include <sys/stat.h> // stat
      • #include <stdbool.h> // bool type
      • bool file_exists (char *filename) {
      • struct stat buffer;
      • return (stat (filename, &buffer) == 0);
      • }
      • 调用:
      • #include <stdio.h> // printf
      • int main(int ac, char **av) {
      • if (ac != 2)
      • return 1;
      • if (file_exists(av[1]))
      • printf("%s exists\n", av[1]);
      • else
      • printf("%s does not exist\n", av[1]);
      • return 0;
      • }
    • Dan Lenski – vote: 95
      • 通常我们需要确定文件是否存在,因为如果不存在的话可能需要我们新建一个。如果我们不需要创建文件的话,Graeme Perrow提到的方式的确有效,否则它可能会受到竞争条件的影响:另一个程序在你确定它是否存在时创建了这个文件,然后你将会打开并且写入它(没必要笑…如果它作为链接文件被创建的话会引发安全问题。)
      • 因此,如果你想要确定文件是否存在,并且在其不存在的时候创建文件时,原子化这个操作,就不会遇到竞争条件了,像这样:
      • #include <fcntl.h>
      • #include <errno.h>
      • fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
      • if (fd < 0) {
      • /* failure */
      • if (errno == EEXIST) {
      • /* the file already existed */
      • ...
      • }
      • } else {
      • /* now you can use the file */
      • }

What’s the best way to check if a file exists in C?

  • Dave Marshall asked:
    • Is there a better way than simply trying to open the file?
      • 有什么比下面更好的途径来尝试打开文件吗?
    • int exists(const char *fname)
    • {
    • FILE *file;
    • if ((file = fopen(fname, "r")))
    • {
    • fclose(file);
    • return 1;
    • }
    • return 0;
    • }
  • Answers:
    • Graeme Perrow – vote: 670
      • Look up the access() function, found in unistd.h. You can replace your function with
        • 试试access()函数,头文件是unist.h。用它来将你的函数改为:
      • if( access( fname, F_OK ) == 0 ) {
      • // file exists
      • } else {
      • // file doesn't exist
      • }
      • You can also use R_OK, W_OK, and X_OK in place of F_OK to check for read permission, write permission, and execute permission (respectively) rather than existence, and you can OR any of them together (i.e. check for both read and write permission using R_OK|W_OK)
        • 使用R_OK, W_OK, X_OK来代替F_OK,可以在确定文件存在的前提上确定文件的读、写、执行权限,并且能够使用 或 来同时使用它们(例如用R_OK|W_OK确定读和写权限)
      • Update: Note that on Windows, you can’t use W_OK to reliably test for write permission, since the access function does not take DACLs into account. access( fname, W_OK ) may return 0 (success) because the file does not have the read-only attribute set, but you still may not have permission to write to the file.
        • 更新:注意,在Windows中,不要用W_OK来测试写权限,因为access函数不会将DACLs考虑在内。access( fname, W_OK) 可能返回0(表成功),因为文件不存在只读属性设置,但你仍然没有该文件的写权限。
    • codebunny – vote: 127
      • Use stat like this:
        • stat
      • #include <sys/stat.h> // stat
      • #include <stdbool.h> // bool type
      • bool file_exists (char *filename) {
      • struct stat buffer;
      • return (stat (filename, &buffer) == 0);
      • }
      • and call it like this:
        • 调用:
      • #include <stdio.h> // printf
      • int main(int ac, char **av) {
      • if (ac != 2)
      • return 1;
      • if (file_exists(av[1]))
      • printf("%s exists\n", av[1]);
      • else
      • printf("%s does not exist\n", av[1]);
      • return 0;
      • }
    • Dan Lenski – vote: 95
      • Usually when you want to check if a file exists, it’s because you want to create that file if it doesn’t. Graeme Perrow’s answer is good if you don’t want to create that file, but it’s vulnerable to a race condition if you do: another process could create the file in between you checking if it exists, and you actually opening it to write to it. (Don’t laugh… this could have bad security implications if the file created was a symlink!)
        • 通常我们需要确定文件是否存在,因为如果不存在的话可能需要我们新建一个。如果我们不需要创建文件的话,Graeme Perrow提到的方式的确有效,否则它可能会受到竞争条件的影响:另一个程序在你确定它是否存在时创建了这个文件,然后你将会打开并且写入它(没必要笑…如果它作为链接文件被创建的话会引发安全问题。)
      • If you want to check for existence and create the file if it doesn’t exist, atomically so that there are no race conditions, then use this:
        • 因此,如果你想要确定文件是否存在,并且在其不存在的时候创建文件时,原子化这个操作,就不会遇到竞争条件了,像这样:
      • #include <fcntl.h>
      • #include <errno.h>
      • fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
      • if (fd < 0) {
      • /* failure */
      • if (errno == EEXIST) {
      • /* the file already existed */
      • ...
      • }
      • } else {
      • /* now you can use the file */
      • }

You may also like...

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注