如何使用fstream::open()函数在C++中检查文件是否存在

14

我正在使用fstream库与文件打交道。基本上,我需要知道某个文件是否存在。在c++在线文档中,关于open(),它写道:

返回值

如果函数无法打开文件,则为流设置failbit状态标志(如果使用成员异常注册了该状态标志,则可能抛出ios_base::failure)。

它说没有指定返回值。但在失败的情况下,会设置一个标志。我的问题是,我应该如何访问那个标志,或者更好地问,我应该如何查看open()是否成功。

到目前为止,我的代码如下:

int Log::add()
{
    fstream fileStream;

    fileStream.open("logs.txt");
}

fileStream.is_open()是什么?请参考http://en.cppreference.com/w/cpp/io/basic_ifstream/is_open。 - Alexis Wilke
那么在失败的情况下,标志和异常怎么办? is_open 在 open() 后立即使用吗? - Mostafa Talebi
C++在这个领域中相当糟糕。有两个标志:failbad可以进行测试,但它并不能告诉你文件是否受保护、不存在或路径错误... - Alexis Wilke
4个回答

21
它说如果文件无法打开,它将设置 failbit。因此,您可以检查该位:

它说如果文件无法打开,它将设置failbit。因此,您可以检查该位:

fileStream.open("logs.txt");
if (fileStream.fail()) {
    // file could not be opened
}

实际上,这里也可以只使用 if (fileStream),因为 iosifstreamofstreamfstream 的基类)有一个转换运算符到 bool

不必担心失败异常。您可以通过调用 ios::exceptions 要求在出现故障时抛出异常,但默认情况下不会在出现故障时抛出异常。

请注意,这并不能告诉您文件无法打开的原因。可能是文件不存在,在路径中的某个目录不存在,您没有权限打开文件,程序已达到它可以打开的文件数限制等等。没有可移植的方法来确定原因。


请注意,使用is_open()更安全。在我的经验中,坏的和失败的位不总是在调用之间正确重置... - Alexis Wilke
还要注意.good(),它表示eofbitfailbitbadbit三者都没有设置,这也会捕获EOF条件。 - Andrew Siplas

11

您的方法并没有检查存在性,而是可访问性。可以像这样检查存在性:

#include <sys/stat.h>

inline bool exists (const std::string& filename) {
  struct stat buffer;   
  return (stat (filename.c_str(), &buffer) == 0); 
}

在C++14中可以使用如下写法:

#include <experimental/filesystem>

bool exist = std::experimental::filesystem::exists(filename);

C++17中的&:(参考资料)

#include <filesystem>

bool exist = std::filesystem::exists(filename);

6
请注意,“文件存在”和“文件可以打开”之间存在差异。
要检查文件是否存在(并且您确实不需要打开/读取/写入文件),请使用fstat或其c++对应项 - 您不需要任何权限来查询信息。
请注意,如果您想在打开文件之前检查文件是否存在,则做法是错误的。条件可能会在您检查和实际尝试打开文件之间发生变化。一般来说,您只需直接使用打开/创建选项打开文件,而无需先进行检查。

12
它的 C++ 对应物是什么? - kuga

4

有两个方法is_openfail,例如:

string path = "not_exists.txt";
ifstream fin(path);

if(fin.is_open()){
    cout<<"file is open"<<endl;
} else{
    cout<<"file isn't open"<<endl;
}

if(fin.fail()){
    cout<<"file open fail"<<endl;
} else{
    cout<<"file open success"<<endl;
}

以下是输出的结果:

图片描述在此处输入

图片描述在此处输入

请参考以下网址: http://www.cplusplus.com/reference/fstream/ifstream/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接