17

Is there any API in 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?

erip
  • 16,374
  • 11
  • 66
  • 121
CodeRider
  • 1,750
  • 6
  • 18
  • 34

13 Answers13

10

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;
}
Amit
  • 677
  • 8
  • 15
  • Sorry that I cant give you an upvote since I dont have enough reputation. Anyway its a different approach – CodeRider Mar 19 '13 at 11:24
  • Well, I can: +1. Honestly, I don't understand how this work...(a link??). Also better return long long. – qPCR4vir Mar 20 '13 at 18:57
  • I 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. – Amit Mar 21 '13 at 09:02
  • 4
    @krimir: Not unless you install UnxUtils or MSYS or a similar package that contains `du` and `cut` as well as `bash` first, and not unless you modify it, because as it is (using pipe and output redirection), it sure won't work. – Damon Jul 24 '13 at 13:55
9

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;
}
qPCR4vir
  • 3,521
  • 1
  • 22
  • 32
  • 2
    what is complete() from ? – ybdesire Apr 11 '20 at 23:53
  • First: 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) – chinnychinchin Jun 28 '20 at 23:24
5

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;
    }
Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147
  • +1: but you forgat to initialize file_size, and probably you need to path filePath(complete (dirIte->path(), folderPath)); – qPCR4vir Mar 19 '13 at 14:09
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;
}
pooya13
  • 2,060
  • 2
  • 23
  • 29
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

Rohit Vyas
  • 1,949
  • 3
  • 19
  • 28
1

The file system functions are integral part of each operative system, written mostly in C and assembler, not C++, each C++ library implementation for this are in one way or another a wrapper of this functions. Taking on count the effort and if you will not use your implementation in different OS, maybe is a good idea to use this functions directly and save some overhead and time.

Best regards.

JP Cordova
  • 119
  • 9
  • hmmm... there are many "wraper": MFC, .NET, Qt, etc. Are all bad? – qPCR4vir Mar 19 '13 at 17:08
  • **Not 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. – JP Cordova Mar 20 '13 at 15:59
  • Of 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. – qPCR4vir Mar 20 '13 at 19:06
1

I have my types definition file with:

typedef std::wstring String;
typedef std::vector<String> StringVector;
typedef unsigned long long uint64_t;

and code is:

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(".."));
}

This uses UNICODE and returns failed dirs if you want that.

To call use:

StringVector vect;
CalculateDirSize(L"C:\\boost_1_52_0", &vect);
CalculateDirSize(L"C:\\boost_1_52_0");

But never pass size

ST3
  • 8,826
  • 3
  • 68
  • 92
  • What 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. – hennessy Nov 09 '13 at 12:07
  • @hennessy you need to include `vector`, `string`, `Windows.h`. It looks like thats all, what error do you get? – ST3 Nov 09 '13 at 12:38
  • Now I tried with these included: #include #include #include - 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' 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 Nov 09 '13 at 14:06
  • I am compiling with Code::Blocks using MinGW if that matters in this case. – hennessy Nov 09 '13 at 14:18
  • Your project doesn't use UNICODE, you need either use UNICODE or use `std::string` instead of `std::wstring` – ST3 Nov 09 '13 at 15:18
  • Thanks 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. – hennessy Nov 09 '13 at 16:30
1
//use FAT32   
#undef UNICODE        // to flag window deactive unicode
#include<Windows.h>  //to use windows api
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#pragma pack(1)  //tell compiler do'nt do prag
struct BPB
{
BYTE            JMP[3];
BYTE            OEM[8];
WORD            NumberOfBytesPerSector;
BYTE            NumberOfSectorsPerCluster;
WORD            NumberOfReservedSectors;
BYTE            NumberOfFATs;
WORD            NumberOfRootEntries16;
WORD            LowNumbferOfSectors;
BYTE            MediaDescriptor;
WORD            NumberOfSectorsPerFAT16;
WORD            NumberOfSectorsPerTrack;
WORD            NumberOfHeads;
DWORD           NumberOfHiddenSectors;
DWORD           HighNumberOfSectors;

DWORD           NumberOfSectorsPerFAT32;
WORD            Flags;
WORD            FATVersionNumber;
DWORD           RootDirectoryClusterNumber;
WORD            FSInfoSector;
WORD            BackupSector;
BYTE            Reserver[12];
BYTE            BiosDrive;
BYTE            WindowsNTFlag;
BYTE            Signature;
DWORD           VolumeSerial;
BYTE            VolumeLabel[11];
BYTE            SystemID[8];
BYTE            CODE[420];
WORD            BPBSignature;
};
//-----------------------------------------------------------
struct DirectoryEntry
{
BYTE Name[11];
BYTE Attributes;
BYTE Reserved;
BYTE CreationTimeTenth;
WORD CreationTime;
WORD CreationDate;
WORD LastAccessTime;
WORD HiClusterNumber;
WORD WriteTime;
WORD WriteDate;
WORD LowClusterNumber;
DWORD FileSize;   //acual size of file
};
//---------------------------------------------------
void dirFunction(string s){
string path = "\\\\.\\" + s + ":";
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ|GENERIC_WRITE,
    FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);//open partition 
BPB bootSector;//var from bootSector structure
DWORD readBytes = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
    cout << "Error " << GetLastError()<<endl;
    return;
}
ReadFile(hFile, (BYTE*)&bootSector, sizeof(bootSector), &readBytes, 0);//read partition and load bootSector information inside our structure
LONG t = 0;
ULONG distance = bootSector.NumberOfReservedSectors +
    bootSector.NumberOfFATs*bootSector.NumberOfSectorsPerFAT32;//distance from begine until Root Directory or content of partetion
distance *= bootSector.NumberOfBytesPerSector;//convert distance number to bytes value

SetFilePointer(hFile, distance, &t, FILE_BEGIN);//set pointer to root directory begine or begine of data
int clusterSize = bootSector.NumberOfBytesPerSector*bootSector.NumberOfSectorsPerCluster; //cluster size 
int NumberOfEntries = clusterSize / sizeof(DirectoryEntry); //number of record inside cluster
DirectoryEntry*  root = new DirectoryEntry[NumberOfEntries];//descripe the partetion
ReadFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
DWORD clusterNumber;
for (int i = 0; i < NumberOfEntries; i++)
{
    if (root[i].Name[0] == 0)//there no entery after this
        break;
    if (root[i].Name[0] == 0xE5)
        continue;
    if ((root[i].Attributes & 0xF) == 0xF)
        continue;
    for (int j = 0; j < 8; j++)
        cout << root[i].Name[j];
    if((root[i].Attributes & 0x10) != 0x10){
        cout<<".";
    for (int j = 8; j < 11; j++)
        cout << root[i].Name[j];
    }
    if ((root[i].Attributes & 0x10) == 0x10){
        cout << "\t<Folder>" ;
    }else{

        cout<<"\t<File>" ;
    }
    clusterNumber = root[i].HiClusterNumber << 16;
    clusterNumber |= root[i].LowClusterNumber;
    cout <<"\t"<<root[i].FileSize<<"bytes" << "\t" << clusterNumber<<"cluster" << endl;
}

CloseHandle(hFile);
}
//---------------------------------------------------------------
string convertLowerToUpper(string f){

string temp = "";
for (int i = 0; i < f.size(); i++){

    temp += toupper(f[i]);
}

return temp;
}
//---------------------------------------------------------------
string getFileName(BYTE filename[11]){
string name = "";
for (int i = 0; i < 8; i++){
    if (filename[i] != ' ')
        name += filename[i];
    }
return (name);

}
//------------------------------------------------------------------
int findEntryNumber(DirectoryEntry*  root, int NumberOfEntries, string required){
string n;
int j = 0;
for (int i = 0; i < NumberOfEntries; i++){

    if (strcmp((getFileName(root[i].Name).c_str()), convertLowerToUpper(required).c_str()) == 0){

        return i;
    }


}

return -1;
}
//---------------------------------------------------------------
void typeFunction(string fileName, string s){
string path = "\\\\.\\" + s + ":";
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ|GENERIC_WRITE,
    FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);//open partition 
BPB bootSector;//var from bootSector structure
DWORD readBytes = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
    cout << "Error " << GetLastError()<<endl;
    return;
}
ReadFile(hFile, (BYTE*)&bootSector, sizeof(bootSector), &readBytes, 0);//read partition and load bootSector information inside our structure
LONG t = 0;
ULONG distance = bootSector.NumberOfReservedSectors +
    bootSector.NumberOfFATs*bootSector.NumberOfSectorsPerFAT32;//distance from begine until Root Directory or content of partetion
distance *= bootSector.NumberOfBytesPerSector;//convert distance number to bytes value

SetFilePointer(hFile, distance, &t, FILE_BEGIN);//set pointer to root directory begine or begine of data
int clusterSize = bootSector.NumberOfBytesPerSector*bootSector.NumberOfSectorsPerCluster; //cluster size 
int NumberOfEntries = clusterSize / sizeof(DirectoryEntry); //number of record inside cluster
DirectoryEntry*  root = new DirectoryEntry[NumberOfEntries];//descripe the partetion
ReadFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
DWORD clusterNumber;
int index = findEntryNumber(root, NumberOfEntries, fileName);
if (index == -1){

    cout << "File is not found" << endl;
    return;
}
if (((root[index].Attributes & 0x10) == 0x10) ){

    cout << "Is not file name" << endl;
    return;
}
clusterNumber = root[index].HiClusterNumber << 16;
clusterNumber |= root[index].LowClusterNumber;
ULONG temp = (clusterNumber - 2) * clusterSize;
distance += temp;
t = 0;
SetFilePointer(hFile, distance, &t, FILE_BEGIN);
BYTE* buffer = new BYTE[clusterSize];
readBytes = 0;


    ReadFile(hFile, (BYTE*)buffer, clusterSize, &readBytes, 0);

    for (int i = 0; i < root[index].FileSize; i++){

        cout << buffer[i];
    }

    cout << endl;
    CloseHandle(hFile);

}
 //----------------------------------------------------------------------
void delFunction(string filename, string s){
string path = "\\\\.\\" + s + ":";
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ|GENERIC_WRITE,
    FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);//open partition 
BPB bootSector;//var from bootSector structure
DWORD readBytes = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
    cout << "Error " << GetLastError()<<endl;
    return;
}
ReadFile(hFile, (BYTE*)&bootSector, sizeof(bootSector), &readBytes, 0);//read partition and load bootSector information inside our structure
LONG t = 0;
ULONG distance = bootSector.NumberOfReservedSectors +
    bootSector.NumberOfFATs*bootSector.NumberOfSectorsPerFAT32;//distance from begine until Root Directory or content of partetion
distance *= bootSector.NumberOfBytesPerSector;//convert distance number to bytes value

SetFilePointer(hFile, distance, &t, FILE_BEGIN);//set pointer to root directory begine or begine of data
int clusterSize = bootSector.NumberOfBytesPerSector*bootSector.NumberOfSectorsPerCluster; //cluster size 
int NumberOfEntries = clusterSize / sizeof(DirectoryEntry); //number of record inside cluster
DirectoryEntry*  root = new DirectoryEntry[NumberOfEntries];//descripe the partetion
ReadFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
DWORD clusterNumber;
readBytes = 0;
t = 0;
int index = findEntryNumber(root, NumberOfEntries, filename);
if (index == -1){

    cout << "FIle is not found" << endl;
    return;
}
if ((root[index].Attributes & 0x10) == 0x10){

    cout << "Is not file name" << endl;
    return;
}

//delete file
root[index].Name[0] = 0xE5;
SetFilePointer(hFile, distance, &t, FILE_BEGIN);
WriteFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
cout<<filename<<" is deleted\n";

CloseHandle(hFile);

}
//----------------------------------------------------------------------
string removeExtention(string s){

string t = "";

for (int i = 0; i < s.size(); i++){

    if (s[i] == '.')break;
    t += s[i];
}

return t;

}
//-------------------------------------------------------------------
void main()
{
string swich_value;
string directory;
string file_name;
//dirFunction("G");
cout<<"plz, Enter single Partition character ------> example E or G\n\n";
cin>>directory;
string path = "\\\\.\\" + directory + ":";
cout<<"current directory is "<<path<<endl;
cout<<"Enter Options: \n1- dir \n2- type file_name.extention \n3- del file_name.extention\n\n";
again:
cin>>swich_value;

if(swich_value.at(1)!='i')
    cin>>file_name;
string answer;
switch(swich_value.at(1)){  
case 'i':
    dirFunction(directory);
    cout<<"\nare  you want to do another process: y or n?";
    cin>>answer;
    if (answer.at(0)=='y')
        goto again;
    break;
case 'y':
    typeFunction(removeExtention(file_name), directory);
    cout<<"\nare  you want to do another process: y or n?";
    cin>>answer;
    if (answer.at(0)=='y')
        goto again;
    break;
case 'e':
    delFunction(removeExtention(file_name), directory);
    cout<<"\nare  you want to do another process: y or n?";
    cin>>answer;
    if (answer.at(0)=='y')
        goto again;
    break;


}
}
Mostafa Anter
  • 3,445
  • 24
  • 26
1

You can use "boost::filesystem"

#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

unsigned long long int get_directory_size(const fs::path& directory){
    if (!fs::exists(directory)) return 0;

    if (fs::is_directory(directory)){
        unsigned long long int ret_size = 0;
        fs::directory_iterator m_dir_itr(directory);

        for (m_dir_itr = fs::begin(m_dir_itr); m_dir_itr != fs::end(m_dir_itr); ++m_dir_itr){
            fs::directory_entry m_dir_entry = *m_dir_itr;
            if (fs::is_regular_file(m_dir_entry.path())){
                ret_size += fs::file_size(m_dir_entry.path());
            }else if (fs::is_directory(m_dir_entry.path())){
                ret_size += get_directory_size(m_dir_entry.path());
            }
        }

        return ret_size;
    } else if (fs::is_regular_file(directory)){
        return fs::file_size(directory);
    }

    return 0;
}

#include <stdio.h>

int main(int /*argc*/, char** /*argv*/) {
    // Assuming 'C:/Folder' be any directory then its size can be found using
    auto folder_size = get_directory_size("C:/Folder");
    printf("Size of 'C:/Folder' is %d\n",folder_size);
    return 0;
}
Mohit
  • 1,225
  • 11
  • 28
1

5 years and not a simple solution with standard C++, that's why I would like to contribute my solution to this question:

uint64_t GetDirSize(const std::string &path)
{
    uint64_t size = 0;
    for (const auto & entry : std::experimental::filesystem::directory_iterator(path))
    {
        if(entry.status().type() == std::experimental::filesystem::file_type::regular)
            size += std::experimental::filesystem::file_size(entry.path());
        if (entry.status().type() == std::experimental::filesystem::file_type::directory)
            size += GetDirSize(entry.path().generic_string());
    }
    return size;
}

Use it for example by calling GetDirSize("C:\\dir_name") if you're using Windows.

Jussi Hietanen
  • 181
  • 1
  • 1
  • 12
1

With the introduction of std::filesystem, you no more have to use any system APIs or any external libraries.

#include <filesystem>
namespace n_fs = ::std::filesystem;
double archive::getFolderSize(std::string path)
{
        double r = 0.0;
        try{
           if (!n_fs::is_directory(path))
           {
                r += (double)n_fs::file_size(path);
           }
           else
           {
                for(auto entry: n_fs::directory_iterator(path))
                getFolderSize(entry.path().string());
            }
        } 
        catch(exception& e)
        { 
            std::cout << e.what() << std::endl();
        }
        return r;
}

int main(){
    double folderSize = getFolderSize("~/dev/"); //Replace with your path
    std::cout << "Size of Folder: " << folderSize;
}
Shivam Jha
  • 88
  • 1
  • 8
0

Try using GetFileSizeEx function. Following is some sample code for this. You need to get the size from the LARGE_INTEGER union though.

#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <io.h>
using namespace std;
int main()
{
    FILE *fp;
    fp = fopen("C:\test.txt","r");
    int fileNo = _fileno(fp);
    HANDLE cLibHandle = (HANDLE)_get_osfhandle(fileNo);
    long int fileSize = 0;
    LARGE_INTEGER fileSizeL;
    GetFileSizeEx(cLibHandle, &fileSizeL);
    return 0;
}
Rakesh K
  • 8,237
  • 18
  • 51
  • 64
  • I 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. – Steve Valliere Mar 19 '13 at 12:12
0

Calculating a folder size in bytes on Windows.

size_t GetFolderSizeInBytes(std::wstring path)
{
    size_t result = 0;
    WIN32_FIND_DATA findData;
    HANDLE hFileHandle;
    std::wstring sourcePath(path);

    if (GetFileAttributes(sourcePath.c_str()) & FILE_ATTRIBUTE_DIRECTORY)
        sourcePath.push_back(L'\\');

    std::wstring fileName(sourcePath);
    fileName.append(L"*");

    hFileHandle = FindFirstFileEx(
            fileName.data(),
            FindExInfoStandard,
            &findData,
            FindExSearchNameMatch,
            NULL,
            FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY);

    if (hFileHandle != INVALID_HANDLE_VALUE)
    {
        do
        {
            if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L".."))
                continue;

            if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            {
                // Folder
                std::wstring newPath = path + L"\\" + findData.cFileName;
                result += GetFolderSizeInBytes(newPath);
            }
            else
            {
                // File
                unsigned long high = findData.nFileSizeHigh;
                unsigned long low = findData.nFileSizeLow;
                size_t size = size_t(high * (MAXWORD + 1)) + low;
                result += size;
            }
        } while (FindNextFile(hFileHandle, &findData));

        FindClose(hFileHandle);
    }

    return result;
}
Juan Carlos
  • 131
  • 1
  • 6