有没有办法获得目录大小/文件夹的大小,而不实际遍历此目录,并增加每个文件的大小? 理想的情况是想使用一些类似boost的库,但win api也可以。
据我所知,你必须在大多数操作系统上迭代。
你可以看一下boost.filesystem,这个库有一个recursive_directory_iterator,它会迭代,尽管在系统上的文件越来越积累的大小。
include <boost/filesystem.hpp> int main() { namespace bf=boost::filesystem; size_t size=0; for(bf::recursive_directory_iterator it("path"); it!=bf::recursive_directory_iterator(); ++it) { if(!bf::is_directory(*it)) size+=bf::file_size(*it); } }
PS:你可以通过使用std :: accumulate和一个lambda,我只是CBA,使这个更清洁
我不认为有这样的事情,至少没有Win32的API函数。
本地为Windows:
void DirectoryInfo::CalculateSize(std::string _path) { WIN32_FIND_DATAA data; HANDLE sh = NULL; sh = FindFirstFileA((_path+"\\*").c_str(), &data); if (sh == INVALID_HANDLE_VALUE ) { return; } do { // skip current and parent if (std::string(data.cFileName).compare(".") != 0 && std::string(data.cFileName).compare("..") != 0) { // if found object is ... if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { // directory, then search it recursievly this->CalculateSize(_path+"\\"+data.cFileName); } else { // otherwise get object size and add it to directory size this->dirSize += (__int64) (data.nFileSizeHigh * (MAXDWORD ) + data.nFileSizeLow); } } } while (FindNextFileA(sh, &data)); // do FindClose(sh); }
你必须遍历这些文件。 如果树中存在硬链接或重分析点,那么获取正确的结果是非常棘手的。 详情请看Raymond Chen的博文 。
Zilog已经写了相当不错的答案,但是我会以相似但不同的方式做出来。
我有我的类型定义文件:
typedef std::wstring String; typedef std::vector<String> StringVector; typedef unsigned long long uint64_t;
代码是:
uint64_t CalculateDirSize(const String &path, StringVector *errVect = NULL, uint64_t size = 0) { WIN32_FIND_DATA data; HANDLE sh = NULL; sh = FindFirstFile((path + L"\\*").c_str(), &data); if (sh == INVALID_HANDLE_VALUE ) { //if we want, store all happened error if (errVect != NULL) errVect ->push_back(path); return size; } do { // skip current and parent if (!IsBrowsePath(data.cFileName)) { // if found object is ... if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) // directory, then search it recursievly size = CalculateDirSize(path + L"\\" + data.cFileName, NULL, size); else // otherwise get object size and add it to directory size size += (uint64_t) (data.nFileSizeHigh * (MAXDWORD ) + data.nFileSizeLow); } } while (FindNextFile(sh, &data)); // do FindClose(sh); return size; } bool IsBrowsePath(const String& path) { return (path == _T(".") || path == _T("..")); }
这使用UNICODE并返回失败的dirs,如果你想要的话。
致电使用:
StringVector vect; CalculateDirSize(L"C:\\boost_1_52_0", &vect); CalculateDirSize(L"C:\\boost_1_52_0");
但是,不要传递size