Cod*_*der 12 c++ windows filesystems directory
c ++中是否有用于获取指定文件夹大小的API ?
如果没有,我如何获得包含所有子文件夹和文件的文件夹的总大小?
让操作系统为您做到这一点:
long long int getFolderSize(string path)
{
// command to be executed
std::string cmd("du -sb ");
cmd.append(path);
cmd.append(" | cut -f1 2>&1");
// execute above command and get the output
FILE *stream = popen(cmd.c_str(), "r");
if (stream) {
const int max_size = 256;
char readbuf[max_size];
if (fgets(readbuf, max_size, stream) != NULL) {
return atoll(readbuf);
}
pclose(stream);
}
// return error val
return -1;
}
Run Code Online (Sandbox Code Playgroud)
实际上我不想使用任何第三方库.只想在纯c ++中实现.
如果您使用MSVC++,您将拥有<filesystem>
"标准C++".
但是使用boost或MSVC - 两者都是"纯C++".
如果你不想使用boost,只有C++ std :: library这个答案有点接近.如您所见,有一个文件系统库提案(修订版4).在这里你可以阅读:
Boost版本的图书馆已经广泛使用了十年.该软件库的Dinkumware版本基于N1975(相当于Boost库的第2版),随Microsoft Visual C++ 2012一起提供.
为了说明这个用法,我调整了@Nayana Adassuriya的答案,只做了很小的修改(好吧,他忘了初始化一个变量,我使用unsigned long long
,最重要的是使用:path filePath(complete (dirIte->path(), folderPath));
在调用其他函数之前恢复完整路径).我已经测试过,它在Windows 7中运行良好.
#include <iostream>
#include <string>
#include <filesystem>
using namespace std;
using namespace std::tr2::sys;
void getFoldersize(string rootFolder,unsigned long long & f_size)
{
path folderPath(rootFolder);
if (exists(folderPath))
{
directory_iterator end_itr;
for (directory_iterator dirIte(rootFolder); dirIte != end_itr; ++dirIte )
{
path filePath(complete (dirIte->path(), folderPath));
try{
if (!is_directory(dirIte->status()) )
{
f_size = f_size + file_size(filePath);
}else
{
getFoldersize(filePath,f_size);
}
}catch(exception& e){ cout << e.what() << endl; }
}
}
}
int main()
{
unsigned long long f_size=0;
getFoldersize("C:\\Silvio",f_size);
cout << f_size << endl;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以通过这种方式使用 boost。您可以尝试对其进行更深入的优化。
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>
using namespace std;
namespace bsfs = boost::filesystem;
void getFoldersize(string rootFolder,long & file_size){
boost::replace_all(rootFolder, "\\\\", "\\");
bsfs::path folderPath(rootFolder);
if (bsfs::exists(folderPath)){
bsfs::directory_iterator end_itr;
for (bsfs::directory_iterator dirIte(rootFolder); dirIte != end_itr; ++dirIte )
{
bsfs::path filePath(dirIte->path());
try{
if (!bsfs::is_directory(dirIte->status()) )
{
file_size = file_size + bsfs::file_size(filePath);
}else{
getFoldersize(filePath.string(),file_size);
}
}catch(exception& e){
cout << e.what() << endl;
}
}
}
}
int main(){
long file_size =0;
getFoldersize("C:\\logs",file_size);
cout << file_size << endl;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
像这样的事情最好避免添加符号(软)链接:
std::uintmax_t directorySize(const std::filesystem::path& directory)
{
std::uintmax_t size{ 0 };
for (const auto& entry : std::filesystem::recursive_directory_iterator(directory))
{
if (entry.is_regular_file() && !entry.is_symlink())
{
size += entry.file_size();
}
}
return size;
}
Run Code Online (Sandbox Code Playgroud)