我想找到最快的方法来检查一个文件是否存在于标准c++ 11, 14, 17,或C。我有成千上万的文件,在对它们做一些事情之前,我需要检查它们是否都存在。在下面的函数中,我可以写什么来代替/* SOMETHING */ ?
inline bool exist(const std::string& name)
{
/* SOMETHING */
}
我想找到最快的方法来检查一个文件是否存在于标准c++ 11, 14, 17,或C。我有成千上万的文件,在对它们做一些事情之前,我需要检查它们是否都存在。在下面的函数中,我可以写什么来代替/* SOMETHING */ ?
inline bool exist(const std::string& name)
{
/* SOMETHING */
}
当前回答
all_of (begin(R), end(R), [](auto&p){ exists(p); })
其中R是你的路径序列,exists()来自未来std或当前boost。如果你自己卷,简单点,
bool exists (string const& p) { return ifstream{p}; }
分支解决方案并不是绝对可怕的,它不会吞噬文件描述符,
bool exists (const char* p) {
#if defined(_WIN32) || defined(_WIN64)
return p && 0 != PathFileExists (p);
#else
struct stat sb;
return p && 0 == stat (p, &sb);
#endif
}
其他回答
与PherricOxide的建议相同,但在C中
#include <sys/stat.h>
int exist(const char *name)
{
struct stat buffer;
return (stat (name, &buffer) == 0);
}
备注:在c++ 14中,一旦文件系统TS完成并被采用,解决方案将使用:
std::experimental::filesystem::exists("helloworld.txt");
从c++ 17开始,只有:
std::filesystem::exists("helloworld.txt");
使用MFC可以实现以下功能
CFileStatus FileStatus;
BOOL bFileExists = CFile::GetStatus(FileName,FileStatus);
哪里的文件名是一个字符串表示文件,您正在检查的存在
It depends on where the files reside. For instance, if they are all supposed to be in the same directory, you can read all the directory entries into a hash table and then check all the names against the hash table. This might be faster on some systems than checking each file individually. The fastest way to check each file individually depends on your system ... if you're writing ANSI C, the fastest way is fopen because it's the only way (a file might exist but not be openable, but you probably really want openable if you need to "do something on it"). C++, POSIX, Windows all offer additional options.
While I'm at it, let me point out some problems with your question. You say that you want the fastest way, and that you have thousands of files, but then you ask for the code for a function to test a single file (and that function is only valid in C++, not C). This contradicts your requirements by making an assumption about the solution ... a case of the XY problem. You also say "in standard c++11(or)c++(or)c" ... which are all different, and this also is inconsistent with your requirement for speed ... the fastest solution would involve tailoring the code to the target system. The inconsistency in the question is highlighted by the fact that you accepted an answer that gives solutions that are system-dependent and are not standard C or C++.
我编写了一个测试程序,每个方法都运行了10万次,一半在存在的文件上,一半在不存在的文件上。
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <fstream>
inline bool exists_test0 (const std::string& name) {
ifstream f(name.c_str());
return f.good();
}
inline bool exists_test1 (const std::string& name) {
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
return true;
} else {
return false;
}
}
inline bool exists_test2 (const std::string& name) {
return ( access( name.c_str(), F_OK ) != -1 );
}
inline bool exists_test3 (const std::string& name) {
struct stat buffer;
return (stat (name.c_str(), &buffer) == 0);
}
在5次运行中平均运行100,000个调用的总时间结果,
Method | Time |
---|---|
exists_test0 (ifstream) |
0.485s |
exists_test1 (FILE fopen) |
0.302s |
exists_test2 (posix access()) |
0.202s |
exists_test3 (posix stat()) |
0.134s |
stat()函数在我的系统(Linux,用g++编译)上提供了最好的性能,如果您出于某种原因拒绝使用POSIX函数,那么标准的fopen调用是您最好的选择。