检查 C++ 中是不是存在文件的最佳方法是啥? (跨平台)

Posted

技术标签:

【中文标题】检查 C++ 中是不是存在文件的最佳方法是啥? (跨平台)【英文标题】: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指出的那样。 【参考方案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,参见 ***.com/questions/9591036/…【参考方案4】:

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

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

【讨论】:

见msdn.microsoft.com/en-us/library/14h5k7ff(VS.71).aspx NOT USING BOOST 的好答案 +1,因为这有点过头了,但是从这里提供的内容中写出来并不是一件容易的事,所以我刚刚发布了一个答案.请检查一下。【参考方案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 boost 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);

【讨论】:

以上是关于检查 C++ 中是不是存在文件的最佳方法是啥? (跨平台)的主要内容,如果未能解决你的问题,请参考以下文章

检查 C 中是不是存在文件的最佳方法是啥?

在 C++ 中实现断言检查的最佳方法是啥?

检查属性是不是存在的最佳方法是啥? [复制]

Boto:检查 CloudFormation 堆栈是不是存在的最佳方法是啥?

检查文档是不是存在并根据 CosmosDB 中的结果插入的最佳方法是啥?

如果路径已知,检查 Firestore 记录是不是存在的最佳方法是啥?