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


Answers:


170

使用boost :: filesystem

#include <boost/filesystem.hpp>

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

68
安装庞大的第三方库来做一些应该很简单的事情似乎有点烦恼
c0m4

89
Boost是一个库,在那里开发了许多最终将成为C ++标准库的部分。许多参与Boost的人都是C ++标准的人。因此,boost不仅仅是任何第三方库。如果您使用C ++进行编程,则应该已经安装了boost!
Andreas Magnusson,

我似乎还记得,b :: fs :: exists对网络共享上不存在的文件返回“ true”:“ \\ machine \ share \ this_file_doesnt_exist” => true。上次我检查的是增强1.33时,请谨慎...
rlerallut

如果您的编译器带有tr1实现,则甚至不需要安装Boost。它将在std :: tr1 ::: filesystem中
Nemanja Trifunovic

1
实际上,ASFAIK并未制作TR1,但稍后会添加。在TR1正式草案中,我也没有找到任何引用:open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
Andreas Magnusson,

41

请注意竞争条件:如果文件在“存在”检查与打开时间之间消失,则程序将意外失败。

最好去打开文件,检查是否失败,如果一切正常,则对文件进行一些处理。对于安全性至关重要的代码,这甚至更为重要。

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


30

我是一个非常高兴的推动者,一定会使用Andreas的解决方案。但是,如果您无权访问boost库,则可以使用流库:

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

它不像boost :: filesystem :: exists那样好,因为该文件实际上会被打开...但是,无论如何,这通常是接下来要做的事情。


15
但是使用此代码,如果您没有该文件的权限(即使它存在),您也将跳入if子句。在大多数情况下,这并不重要,但仍然值得一提。
scigor 2011年

1
注意到如果给定参数表示的目录中良好的()也产生真正的,看到stackoverflow.com/questions/9591036/...
FelixJongleur42

12

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

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


1
<sys / types.h>和<sys / stat.h>参见msdn.microsoft.com/en-us/library/14h5k7ff(VS.71).aspx
activout.se,

1
不错的答案+1(不使用BOOST),因为这太过分了,但是从此处提供的内容写出来并不是一件容易的事,所以我只发布了一个答案。请检查一下。
gsamaras

9

怎么access

#include <io.h>

if (_access(filename, 0) == -1)
{
    // File does not exist
}

即使不是标准的io.h,在Windows和Linux上也可以正常使用吗?
08年

1
access()是POSIX函数,可在Linux上通过<unistd.h>使用。
Alex B

9

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

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

7

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


如果您正在编写类似ls程序怎么办?我猜这里的原始海报根本不想打开文件。尽管Posix的stat函数应该为您提供有关文件权限的信息,所以它将解决该问题。
迈克尔

6

如果您的编译器支持C ++ 17,则不需要升压,只需使用 std::filesystem::exists

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

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

3

没有 要求,这将是一个过大的杀伤力


使用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...

可以在此处找到另一个版本。


不是下降投票者,而是这个问题要求一个跨平台的解决方案,并且stat并非在所有平台上都存在。
pavon

0

如果您已经在使用输入文件流类(ifstream),则可以使用其功能fail()

例:

ifstream myFile;

myFile.open("file.txt");

// Check for errors
if (myFile.fail()) {
    cerr << "Error: File could not be found";
    exit(1);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.