How can I find the size of all files located inside a folder?
Solution 1
Actually I don't want to use any third party library. Just want to implement in pure c++.
If you use MSVC++ you have <filesystem>
"as standard C++".
But using boost or MSVC - both are "pure C++".
If you don’t want to use boost, and only the C++ std:: library this answer is somewhat close. As you can see here, there is a Filesystem Library Proposal (Revision 4). Here you can read:
The Boost version of the library has been in widespread use for ten years. The Dinkumware version of the library, based on N1975 (equivalent to version 2 of the Boost library), ships with Microsoft Visual C++ 2012.
To illustrate the use, I adapted the answer of @Nayana Adassuriya , with very minor modifications (OK, he forgot to initialize one variable, and I use unsigned long long
, and most important was to use: path filePath(complete (dirIte->path(), folderPath));
to restore the complete path before the call to other functions). I have tested and it work well in 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;
}
Solution 2
How about letting OS do it for you:
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;
}
Solution 3
You may use boost in this way. You can try to optimize it some deeper.
#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;
}
Solution 4
Size of files in a folder Please have a look at this link
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
__int64 TransverseDirectory(string path)
{
WIN32_FIND_DATA data;
__int64 size = 0;
string fname = path + "\\*.*";
HANDLE h = FindFirstFile(fname.c_str(),&data);
if(h != INVALID_HANDLE_VALUE)
{
do {
if( (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
// make sure we skip "." and "..". Have to use strcmp here because
// some file names can start with a dot, so just testing for the
// first dot is not suffient.
if( strcmp(data.cFileName,".") != 0 &&strcmp(data.cFileName,"..") != 0)
{
// We found a sub-directory, so get the files in it too
fname = path + "\\" + data.cFileName;
// recurrsion here!
size += TransverseDirectory(fname);
}
}
else
{
LARGE_INTEGER sz;
// All we want here is the file size. Since file sizes can be larger
// than 2 gig, the size is reported as two DWORD objects. Below we
// combine them to make one 64-bit integer.
sz.LowPart = data.nFileSizeLow;
sz.HighPart = data.nFileSizeHigh;
size += sz.QuadPart;
}
}while( FindNextFile(h,&data) != 0);
FindClose(h);
}
return size;
}
int main(int argc, char* argv[])
{
__int64 size = 0;
string path;
size = TransverseDirectory("c:\\dvlp");
cout << "\n\nDirectory Size = " << size << "\n";
cin.ignore();
return 0;
}
For more detail PLease CLick Here
Solution 5
Something like this would be better to avoid adding symbolic(soft) links:
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;
}
CodeRider
Software Engineer,India. Developing applications using VC++,C++,MFC,Opengl
Updated on September 18, 2021Comments
-
CodeRider over 2 years
Is there any API in c++ for getting the size of a specified folder?
If not, how can I get the total size of a folder including all subfolders and files?
-
Kiril Kirov about 11 yearsSize of folder? Or size of all files, located in the folder? And which OS?
-
CodeRider about 11 yearsya I meant size of all files in the folder.And the OS is windows
-
Daniel Frey about 11 yearsYou'll need a library, for example Boost.Filesystem.
-
Cyrille about 11 yearsAlmost same question here
-
CodeRider about 11 years@Daniel Frey. Actually I don't want to use any third party library. Just want to implement in pure c++.Any way thanks for the info.
-
CodeRider about 11 years@Cyrille I saw that one, but just want to know if a single api can do that for me.
-
qPCR4vir about 11 yearsAre you using MSVC++ ??
-
-
Kiril Kirov about 11 yearsThis is not a good answer. "Extract" some of the important points from this link and write them here. You may leave the link for "more details".
-
Akanksh about 11 years@meh good point, the link might go stale and would then be of no use to subsequent users asking the same question.
-
CodeRider about 11 yearsThank u all for the kind support.
-
CodeRider about 11 yearsSorry that I cant give you an upvote since I dont have enough reputation. Anyway its a different approach
-
Steve Valliere about 11 yearsI don't think
GetFileSize()
works on folders/directories and the question is about getting the total size of a directory's content. At least, as I understand the question. -
qPCR4vir about 11 years+1: but you forgat to initialize file_size, and probably you need to path filePath(complete (dirIte->path(), folderPath));
-
qPCR4vir about 11 yearshmmm... there are many "wraper": MFC, .NET, Qt, etc. Are all bad?
-
JP Cordova about 11 yearsNot bat or wrong, from my point of view and as I understand, C++ libraries aim to improve portability and hide complications of direct use of underlayer functions and methods offer for the operative systems (big picture). In this case the effort to read directories and summarize file sizes are not different from OS methods and C++ libraries like boost, as you can see in all examples shared in this posts.
-
qPCR4vir about 11 yearsWell, I can: +1. Honestly, I don't understand how this work...(a link??). Also better return long long.
-
qPCR4vir about 11 yearsOf course, I partialy agree with you. But partcularly learning Win32 is sometimes ...hard, and not very C++ (the Q was: a C++ API). Thank for the answer.
-
Amit about 11 yearsI am just using popen (mkssoftware.com/docs/man3/popen.3.asp) to run 'du' (disk usage) command and parsing the output returned by that. I mostly use this approach to debug code where I suspect it could be dying due to some system related issue (say doing 'stat' on file I was reading). I modified it to return long long int as you suggested.
-
Damon almost 11 years@krimir: Not unless you install UnxUtils or MSYS or a similar package that contains
du
andcut
as well asbash
first, and not unless you modify it, because as it is (using pipe and output redirection), it sure won't work. -
hennessy over 10 yearsWhat has to be included to get this code to work? I feel like Ive tried everthing and I still keep getting errors. Ive included windows.h and tried a bunch of other things along with it, it still doesnt work.
-
ST3 over 10 years@hennessy you need to include
vector
,string
,Windows.h
. It looks like thats all, what error do you get? -
hennessy over 10 yearsNow I tried with these included: #include <windows.h> #include <string> #include <vector> - Error: cannot convert 'const wchar_t*' to 'LPCSTR {aka const char*}' for argument '1' to 'void* FindFirstFileA(LPCSTR, LPWIN32_FIND_DATAA)'| - and - error: 'IsBrowsePath' was not declared in this scope| - and - error: no match for 'operator+' (operand types are 'std::basic_string<wchar_t>' and 'CHAR [260] {aka char [260]}')| ----- I have the 3 typedefs that you made above the function in main.cpp, so its like first the includes, then typedefs, then the CalculateDirSize function and then main().
-
hennessy over 10 yearsI am compiling with Code::Blocks using MinGW if that matters in this case.
-
ST3 over 10 yearsYour project doesn't use UNICODE, you need either use UNICODE or use
std::string
instead ofstd::wstring
-
hennessy over 10 yearsThanks that one helped, I changed std:wstring to std::string and removed the L that was infront of the "//" at the 2 places. What about the IsBrowsePath, though, I have tried declaring it but I just cant figure out how to use it. I still keep getting this error: . \main.cpp|54|error: 'IsBrowsePath' was not declared in this scope| -- It seems to be the last problem that I cant figure out.
-
ybdesire about 4 yearswhat is complete() from ?
-
chinnychinchin almost 4 yearsFirst: dirIte->path() is sufficient for populating the filePath properly. "complete()" is not necessarily. Second: getFoldersize recursive call in the else body, should take filePath as a string ( can use filePath.string() if you are using experimental/filesystem v1 with C++17/20)