轉(zhuǎn)載https://blog.csdn.net/guotianqing/article/details/100766120
c++ 判斷文件是否存在的幾種方法
一般而言,下述方法都可以檢查文件是否存在:
使用ifstream打開文件流串纺,成功則存在,失敗則不存在
以fopen讀方式打開文件搓萧,成功則存在缤弦,否則不存在
使用access函數(shù)獲取文件狀態(tài),成功則存在压彭,否則不存在
使用stat函數(shù)獲取文件狀態(tài)闻妓,成功則存在菌羽,否則不存在
代碼如下:
#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);
}
參考資料中有性能測試對比,結(jié)果表明由缆,使用 stat() 函數(shù)的方式性能最好注祖。
# Results for total time to run the 100,000 calls averaged over 5 runs,
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**
boost庫
boost.filesystem在發(fā)生錯誤的時(shí)候會拋出異常,但是在大部分情況下這些異常是可以忽略的均唉,例如是晨,在檢查文件是否存在的時(shí)候,發(fā)生錯誤可以等同于文件不存在舔箭。
雖然boost.filesystem也提供了重載函數(shù)罩缴,通過輸出參數(shù)返回錯誤來代替異常蚊逢,但是在每個(gè)調(diào)用點(diǎn)都得定義一個(gè)輸出參數(shù),稍顯麻煩箫章。
所以烙荷,為了簡化客戶代碼,我們實(shí)現(xiàn)了一些包裝函數(shù)檬寂,如下所示:
bool IsFileExistent(const boost::filesystem::path& path) {
boost::system:error_code error;
return boost::filesystem::is_regular_file(path, error);
}
上面的函數(shù)用來檢查文件是否存在终抽,使用了boost::filesystem::is_regular_file。當(dāng)path指向一個(gè)“常規(guī)文件”的時(shí)候桶至,認(rèn)為該文件存在昼伴;否則其它任何情況都認(rèn)為文件不存在。
對于只有常規(guī)文件的情況镣屹,該函數(shù)沒有問題圃郊。但是,如果還存在其他文件時(shí)女蜈,如符號鏈接文件時(shí)描沟,則返回文件不存在。
事實(shí)上鞭光,用boost::filesystem::status獲取時(shí),會返回symlink_file泞遗,boost.filesystem將它們視為符號鏈接文件惰许。
不論是常規(guī)文件還是符號鏈接文件,呈現(xiàn)給用戶的都是能夠正常使用的文件史辙。
所以汹买,不能單純地用boost::filesystem::is_regular_file來檢查文件是否存在了,下面是包裝函數(shù)的改進(jìn)版本:
bool IsFileExistent(const boost::filesystem::path& path) {
boost::system:error_code error;
auto file_status = boost::filesystem::status(path, error);
if (error) {
return false;
}
if (! boost::filesystem::exists(file_status)) {
return false;
}
if (boost::filesystem::is_directory(file_status)) {
return false;
}
return true;
}
首先聊倔,通過boost::filesystem::status獲取文件的信息晦毙,如果發(fā)生錯誤,則認(rèn)為文件不存在耙蔑。
然后见妒,使用boost::filesystem::exists判斷文件是否存在,該函數(shù)不區(qū)分文件夾和文件甸陌,所以最后還要使用boost::filesystem::is_directory判斷一下是否文件夾须揣,只要不是文件夾,都認(rèn)為文件是存在的钱豁。