【问题标题】:What’s the best way to check if a file exists in C++? (cross platform)检查 C++ 中是否存在文件的最佳方法是什么? (跨平台)
【发布时间】:2010-09-21 01:08:45
【问题描述】:

我已经阅读了What's the best way to check if a file exists in C? (cross platform) 的答案,但我想知道是否有更好的方法可以使用标准 c++ 库来做到这一点?最好根本不尝试打开文件。

stataccess 几乎都无法通过 Google 搜索。我应该#include 来使用这些?

【问题讨论】:

  • 用于访问(实际上可能是 _access)。
  • 是的,正如therefromhere指出的那样。

标签: c++ file file-io


【解决方案1】:

使用boost::filesystem:

#include <boost/filesystem.hpp>

if ( !boost::filesystem::exists( "myfile.txt" ) )
{
  std::cout << "Can't find my file!" << std::endl;
}

【讨论】:

  • 安装一个庞大的第三方库来做一些应该简单的事情似乎有点麻烦
  • Boost 是一个库,其中大部分内容最终将成为 C++ 标准库的一部分。许多参与 boost 的人都是参与 C++ 标准的人。所以 boost 不仅仅是 any 第三方库。如果您使用 C++ 编程,您应该安装 boost!
  • 我似乎记得 b::fs::exists 在网络共享上不存在的文件上返回“true”:“\\machine\share\this_file_doesnt_exist”=> true。我上次检查是在 boost 1.33 上,请谨慎使用...
  • 如果你的编译器带有 tr1 实现,你甚至不需要安装 Boost。它将在 std::tr1::filesystem
  • 其实ASFAIK它并没有做TR1,但会在稍后阶段添加。我在官方 TR1 草案中也没有找到任何参考:open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
【解决方案2】:

注意竞争条件:如果文件在“存在”检查和您打开它之间消失,您的程序将意外失败。

最好去打开文件,检查失败,如果一切正常,然后对文件做一些事情。对于安全关键代码而言,这一点更为重要。

有关安全性和竞争条件的详细信息: http://www.ibm.com/developerworks/library/l-sprace.html

【讨论】:

  • 链接失效了。
【解决方案3】:

我是一个快乐的 boost 用户,肯定会使用 Andreas 的解决方案。但是,如果您无权访问 boost 库,则可以使用流库:

ifstream file(argv[1]);
if (!file)
{
    // Can't open file
}

它不如 boost::filesystem::exists 好,因为文件实际上会被打开......但那通常是你接下来想做的事情。

【讨论】:

  • 但是如果你没有文件的权限,你也会跳到 if 子句,尽管它存在。在大多数情况下,这无关紧要,但仍然值得一提。
  • 注意到如果给定的参数表示一个目录,good() 也会产生 true,参见 stackoverflow.com/questions/9591036/…
【解决方案4】:

使用 stat(),如果它是跨平台的,足以满足您的需求。它不是 C++ 标准,而是 POSIX。

在 MS Windows 上,有 _stat、_stat64、_stati64、_wstat、_wstat64、_wstati64。

【讨论】:

【解决方案5】:

如果你的编译器支持 C++17,你不需要 boost,你可以简单地使用std::filesystem::exists

#include <iostream> // only for std::cout
#include <filesystem>

if (!std::filesystem::exists("myfile.txt"))
{
    std::cout << "File not found!" << std::endl;
}

【讨论】:

    【解决方案6】:

    access怎么样?

    #include <io.h>
    
    if (_access(filename, 0) == -1)
    {
        // File does not exist
    }
    

    【讨论】:

    • io.h 在 windows 和 linux 上是否正常可用,即使它不是标准的?
    • access() 是 POSIX 函数,可通过 Linux 上的 获得。
    【解决方案7】:

    另一种可能性是在流中使用good() 函数:

    #include <fstream>     
    bool checkExistence(const char* filename)
    {
         ifstream Infield(filename);
         return Infield.good();
    }
    

    【讨论】:

      【解决方案8】:

      我会重新考虑尝试找出文件是否存在。相反,您应该尝试以您打算使用它的相同模式打开它(在标准 C 或 C++ 中)。如果在需要使用文件时它不可写,那么知道文件存在有什么用?

      【讨论】:

      • 如果您正在编写类似ls 的程序怎么办?我猜这里的原始海报根本不想打开文件。 Posix 的 stat 函数应该为您提供有关文件权限的信息,因此它可以解决该问题。
      【解决方案9】:

      NO REQUIRED,这将是一个矫枉过正


      使用stat()(虽然如pavon所述,但不是跨平台),如下所示:

      #include <sys/stat.h>
      #include <iostream>
      
      // true if file exists
      bool fileExists(const std::string& file) {
          struct stat buf;
          return (stat(file.c_str(), &buf) == 0);
      }
      
      int main() {
          if(!fileExists("test.txt")) {
              std::cerr << "test.txt doesn't exist, exiting...\n";
              return -1;
          }
          return 0;
      }
      

      输出:

      C02QT2UBFVH6-lm:~ gsamaras$ ls test.txt
      ls: test.txt: No such file or directory
      C02QT2UBFVH6-lm:~ gsamaras$ g++ -Wall main.cpp
      C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
      test.txt doesn't exist, exiting...
      

      另一个版本(和那个)可以在here找到。

      【讨论】:

      • 不是反对者,而是要求跨平台解决方案的问题,并且 stat 并非在所有平台上都存在。
      【解决方案10】:

      如果你已经在使用输入文件流类(ifstream),你可以使用它的函数fail()

      示例:

      ifstream myFile;
      
      myFile.open("file.txt");
      
      // Check for errors
      if (myFile.fail()) {
          cerr << "Error: File could not be found";
          exit(1);
      }
      

      【讨论】:

        猜你喜欢
        • 2010-09-18
        • 2011-12-18
        • 1970-01-01
        • 2011-05-25
        • 2012-08-29
        相关资源
        最近更新 更多