c++判斷文件是否存在的方法匯總
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); }
參考資料中有性能測試對比,結果表明,使用 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ā)生錯誤的時候會拋出異常,但是在大部分情況下這些異常是可以忽略的,例如,在檢查文件是否存在的時候,發(fā)生錯誤可以等同于文件不存在。
雖然boost.filesystem也提供了重載函數(shù),通過輸出參數(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。當path指向一個“常規(guī)文件”的時候,認為該文件存在;否則其它任何情況都認為文件不存在。
對于只有常規(guī)文件的情況,該函數(shù)沒有問題。但是,如果還存在其他文件時,如符號鏈接文件時,則返回文件不存在。
事實上,用boost::filesystem::status獲取時,會返回symlink_file,boost.filesystem將它們視為符號鏈接文件。
不論是常規(guī)文件還是符號鏈接文件,呈現(xiàn)給用戶的都是能夠正常使用的文件。
所以,不能單純地用boost::filesystem::is_regular_file來檢查文件是否存在了,下面是包裝函數(shù)的改進版本:
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ā)生錯誤,則認為文件不存在。
然后,使用boost::filesystem::exists判斷文件是否存在,該函數(shù)不區(qū)分文件夾和文件,所以最后還要使用boost::filesystem::is_directory判斷一下是否文件夾,只要不是文件夾,都認為文件是存在的。
c++判斷文件是否存在+獲取文件大小
判斷文件是存在
GetFileAttributes( m_Output) == -1 //判斷文件是否存在若不存在返回-1
返回字段 | 返回值 | 屬性類型 |
FILE_ATTRIBUTE_READONLY | 1 | 只讀 |
FILE_ATTRIBUTE_HIDDEN | 2 | 隱藏 |
FILE_ATTRIBUTE_SYSTEM | 4 | 系統(tǒng) |
FILE_ATTRIBUTE_DIRECTORY | 16 | 目錄 |
FILE_ATTRIBUTE_ARCHIVE | 32 | 存檔 |
FILE_ATTRIBUTE_DEVICE | 64 | 保留 |
FILE_ATTRIBUTE_NORMAL | 128 | 正常 |
FILE_ATTRIBUTE_TEMPORARY | 256 | 臨時 |
FILE_ATTRIBUTE_SPARSE_FILE | 512 | 稀疏文件 |
FILE_ATTRIBUTE_REPARSE_POINT | 1024 | 超鏈接或快捷方式 |
FILE_ATTRIBUTE_COMPRESSED | 2048 | 壓縮 |
FILE_ATTRIBUTE_OFFLINE | 4096 | 脫機 |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | 8192 | 索引 |
FILE_ATTRIBUTE_ENCRYPTED | 16384 | 加密 |
FILE_ATTRIBUTE_VIRTUAL | 65536 | 虛擬 |
橙色標記的屬性為 Windows 系統(tǒng)中文件的公有屬性,其中 “ 只讀 ” 、 “ 隱藏 ” 、 “ 系統(tǒng) ” 、 “ 存檔 ” 為文件的四種基本屬性。
compressed , content_indexed , encrypted 只存在于 NTFS 分區(qū)中。
文件去掉全部屬性后(四種基本屬性),將自動標記為 normal 。同時具有 system 和 hidden 屬性的文件會在系統(tǒng)中徹底隱形,這也是病毒常用的伎倆。
commpressed 和 encrypted 不能共存。默認情況下文件有 content_indexed 屬性。
獲取文件大小
ULONGLONG size; CFileStatus fileStatus; //文件絕對路徑 if (CFile::GetStatus(m_Output, fileStatus)) size = fileStatus.m_size;
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Visual Studio 2022中創(chuàng)建的C++項目無法使用萬能頭<bits/stdc++.h>的
如果大家也遇到下面這種問題,可能是沒有include文件夾中沒有bits/stdc++.h,這篇文章主要介紹了Visual Studio 2022中創(chuàng)建的C++項目無法使用萬能頭<bits/stdc++.h>的解決方案,感興趣的朋友跟隨小編一起看看吧2024-02-02C語言中#define與typedef的互換細節(jié)詳解
本篇文章是對C語言中#define與typedef的互換細節(jié)進行了詳細的分析介紹,需要的朋友參考下2013-05-05C++如何比較兩個字符串或string是否相等strcmp()和compare()
這篇文章主要介紹了C++如何比較兩個字符串或string是否相等strcmp()和compare()問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11