使用标准 C++/C++11/C 检查文件是否存在的最快方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12774207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fastest way to check if a file exist using standard C++/C++11/C?
提问by Vincent
I would like to find the fastest way to check if a file exist in standard C++11, C++, or C. I have thousands of files and before doing something on them I need to check if all of them exist. What can I write instead of /* SOMETHING */
in the following function?
我想找到检查标准 C++11、C++ 或 C 中是否存在文件的最快方法。我有数千个文件,在对它们执行某些操作之前,我需要检查它们是否都存在。我可以写什么来代替/* SOMETHING */
下面的函数?
inline bool exist(const std::string& name)
{
/* SOMETHING */
}
回答by PherricOxide
Well I threw together a test program that ran each of these methods 100,000 times, half on files that existed and half on files that didn't.
好吧,我拼凑了一个测试程序,该程序运行这些方法中的每一个 100,000 次,一半在存在的文件上,一半在不存在的文件上。
#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);
}
Results for total time to run the 100,000 calls averaged over 5 runs,
运行 100,000 次调用的总时间平均超过 5 次运行的结果,
Method exists_test0 (ifstream): **0.485s**
Method exists_test1 (FILE fopen): **0.302s**
Method exists_test2 (posix access()): **0.202s**
Method exists_test3 (posix stat()): **0.134s**
The stat()
function provided the best performance on my system (Linux, compiled with g++
), with a standard fopen
call being your best bet if you for some reason refuse to use POSIX functions.
该stat()
函数在我的系统(Linux,使用 编译g++
)上提供了最佳性能,fopen
如果您出于某种原因拒绝使用 POSIX 函数,标准调用是您最好的选择。
回答by Vincent
Remark : in C++14 and as soon as the filesystem TSwill be finished and adopted, the solution will be to use:
备注:在 C++14 中,一旦文件系统 TS完成并采用,解决方案将是使用:
std::experimental::filesystem::exists("helloworld.txt");
and since C++17, only:
从 C++17 开始,只有:
std::filesystem::exists("helloworld.txt");
回答by harryngh
I use this piece of code, it works OK with me so far. This does not use many fancy features of C++:
我使用这段代码,到目前为止它对我来说还可以。这并没有使用 C++ 的许多花哨的特性:
bool is_file_exist(const char *fileName)
{
std::ifstream infile(fileName);
return infile.good();
}
回答by Jim Balter
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 mightbe 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.
这取决于文件所在的位置。例如,如果它们都应该在同一个目录中,您可以将所有目录条目读入哈希表,然后根据哈希表检查所有名称。在某些系统上,这可能比单独检查每个文件更快。单独检查每个文件的最快方法取决于您的系统...如果您正在编写 ANSI C,最快的方法是fopen
因为它是唯一的方法(文件可能存在但不可打开,但如果您想打开文件,您可能真的想要可打开)需要“对它做点什么”)。C++、POSIX、Windows 都提供了额外的选项。
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++.
在此期间,让我指出您的问题的一些问题。您说您想要最快的方式,并且您有数千个文件,但是随后您要求提供用于测试单个文件的函数的代码(该函数仅在 C++ 中有效,在 C 中无效)。通过对解决方案做出假设,这与您的要求相矛盾…… XY 问题的一个案例。您还说“在标准的 c++11(or)c++(or)c”中……它们都是不同的,这也与您对速度的要求不一致……最快的解决方案是将代码裁剪为目标系统。您接受了一个答案,该答案提供了与系统相关且不是标准 C 或 C++ 的解决方案,这一事实突显了问题中的不一致。
回答by anhoppe
For those who like boost:
对于喜欢boost的人:
boost::filesystem::exists(fileName)
回答by Viktor Liehr
Without using other libraries, I like to use the following code snippet:
在不使用其他库的情况下,我喜欢使用以下代码片段:
#ifdef _WIN32
#include <io.h>
#define access _access_s
#else
#include <unistd.h>
#endif
bool FileExists( const std::string &Filename )
{
return access( Filename.c_str(), 0 ) == 0;
}
This works cross-platform for Windows and POSIX-compliant systems.
这适用于 Windows 和 POSIX 兼容系统的跨平台。
回答by Ramon La Pietra
Same as suggested by PherricOxide but in C
与 PherricOxide 建议的相同,但在 C 中
#include <sys/stat.h>
int exist(const char *name)
{
struct stat buffer;
return (stat (name, &buffer) == 0);
}
回答by LOLOLOL
inline bool exist(const std::string& name)
{
ifstream file(name);
if(!file) // If the file was not found, then file is 0, i.e. !file=1 or true.
return false; // The file was not found.
else // If the file was found, then file is non-0.
return true; // The file was found.
}
回答by ravin.wang
Another 3 options under windows:
windows下的另外3个选项:
1
1
inline bool exist(const std::string& name)
{
OFSTRUCT of_struct;
return OpenFile(name.c_str(), &of_struct, OF_EXIST) != INVALID_HANDLE_VALUE && of_struct.nErrCode == 0;
}
2
2
inline bool exist(const std::string& name)
{
HANDLE hFile = CreateFile(name.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != NULL && hFile != INVALID_HANDLE)
{
CloseFile(hFile);
return true;
}
return false;
}
3
3
inline bool exist(const std::string& name)
{
return GetFileAttributes(name.c_str()) != INVALID_FILE_ATTRIBUTES;
}
回答by parv
You may also do bool b = std::ifstream('filename').good();
. Without the branch instructions(like if) it must perform faster as it needs to be called thousands of times.
你也可以这样做bool b = std::ifstream('filename').good();
。如果没有分支指令(如 if),它必须执行得更快,因为它需要被调用数千次。