How can I find the size of all files located inside a folder?

后端 未结 12 2367
萌比男神i
萌比男神i 2020-12-06 05:49

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?

相关标签:
12条回答
  • 2020-12-06 05:57
    //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;
    
    
    }
    }
    
    0 讨论(0)
  • 2020-12-06 06:01

    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;
    }
    
    0 讨论(0)
  • 2020-12-06 06:02

    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;
    }
    
    0 讨论(0)
  • 2020-12-06 06:03

    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;
    }
    
    0 讨论(0)
  • 2020-12-06 06:09

    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;
    }
    
    0 讨论(0)
  • 2020-12-06 06:12

    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;
        }
    
    0 讨论(0)
提交回复
热议问题