我想找到最快的方法来检查一个文件是否存在于标准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 */
}
当前回答
我使用这段代码,到目前为止,它工作得很好。它没有使用c++的许多奇特的特性:
bool is_file_exist(const char *fileName)
{
std::ifstream infile(fileName);
return infile.good();
}
其他回答
你也可以使用bool b = std::ifstream('filename').good();。如果没有分支指令(比如if),它必须执行得更快,因为它需要被调用数千次。
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.
}
测试文件是否存在的最快和最安全的方法是根本不单独/显式地测试它。也就是说,看看你是否能找到一种方法来取代普通
if(exists(file)) { /* point A */
/* handle existence condition */
return;
}
do_something_with(file); /* point B */
随着
r = do_something_with_unless_exists(file);
if(r == 0)
success;
else if(errno == EEXIST)
/* handle existence condition */
else
/* handle other error */
除了速度更快之外,这还消除了第一个解决方案中固有的竞争条件(特别是“TOC/TOU”),即文件在点A和点B之间存在的可能性。
显然,第二个解决方案假定存在一种原子方法来执行do_something_with_unless_exists操作。通常总会有办法的,但有时你得四处寻找。
创建文件:使用O_CREAT和O_EXCL调用open()。 创建一个纯C文件,如果你有C11:调用fopen()与"wx"。(我昨天才知道这个。) 创建目录:只需调用mkdir(),然后检查errno == EEXIST。 获取锁:任何称职的锁定系统都已经拥有一个原子性的“只要没有其他人拥有就获取锁”原语。
(还有其他的,但这些是我现在能想到的。)
[脚注:在Unix的早期,没有特定的、专用的工具可用于普通进程进行锁定,所以如果你想建立一个互斥锁,这通常是通过创建一个特定的空目录来实现的,因为mkdir系统调用总是能够根据先前的存在或不存在而原子地失败或成功。]
在不使用其他库的情况下,我喜欢使用以下代码片段:
#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;
}
这适用于Windows和posix兼容系统的跨平台。
备注:在c++ 14中,一旦文件系统TS完成并被采用,解决方案将使用:
std::experimental::filesystem::exists("helloworld.txt");
从c++ 17开始,只有:
std::filesystem::exists("helloworld.txt");