检查 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++ 库来做到这一点?最好根本不尝试打开文件。
stat
和 access
几乎都无法通过 Google 搜索。我应该#include
来使用这些?
【问题讨论】:
使用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。
【讨论】:
如果你的编译器支持 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 上的另一种可能性是在流中使用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++ 中是不是存在文件的最佳方法是啥? (跨平台)的主要内容,如果未能解决你的问题,请参考以下文章
Boto:检查 CloudFormation 堆栈是不是存在的最佳方法是啥?