15

指定されたフォルダのサイズを取得するためののAPIはありますか?

そうでない場合、すべてのサブフォルダーとファイルを含むフォルダーの合計サイズを取得するにはどうすればよいですか?

4

13 に答える 13

10

OSに任せてみませんか:

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;
}
于 2013-03-19T11:14:30.210 に答える
9

実際、サードパーティのライブラリは使用したくありません。純粋な C++ で実装したいだけです。

MSVC++ を使用している場合は、<filesystem>「標準 C++ として」使用できます。 ただし、ブーストまたは MSVC を使用すると、どちらも「純粋な C++」になります。

ブーストを使用せず、C++ std:: ライブラリのみを使用する場合、この回答はやや近いです。ここでわかるように、 Filesystem Library Proposal (Revision 4) があります。ここで読むことができます:

ライブラリの Boost バージョンは、10 年間広く使用されています。N1975 (Boost ライブラリのバージョン 2 に相当) に基づく Dinkumware バージョンのライブラリには、Microsoft Visual C++ 2012 が同梱されています。

使用法を説明するために、@Nayana Adassuriya の回答をごくわずかな変更を加えて適応させました (OK、彼は 1 つの変数を初期化するのを忘れていました。私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;
}
于 2013-03-19T14:06:07.833 に答える
5

この方法でブーストを使用できます。より深く最適化を試みることができます。

#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;
    }
于 2013-03-19T10:36:43.303 に答える
4

フォルダ内のファイルのサイズ このリンクをご覧ください

#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;
}

詳細については、ここをクリックしてください

于 2013-03-19T09:36:00.357 に答える
1

ファイルシステム関数は、各オペレーティングシステムの不可欠な部分であり、主にC ++ではなくCとアセンブラで記述されています。このための各C++ライブラリの実装は、何らかの形でこの関数のラッパーです。労力を考慮し、異なるOSで実装を使用しない場合は、この関数を直接使用して、オーバーヘッドと時間を節約することをお勧めします。

よろしくお願いします。

于 2013-03-19T14:25:44.407 に答える
1

タイプ定義ファイルには次のものがあります。

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 を使用し、必要に応じて失敗したディレクトリを返します。

呼び出すには:

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

でも決して通らないsize

于 2013-07-25T13:43:24.620 に答える
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;


}
}
于 2015-11-26T22:46:47.177 に答える
0

GetFileSizeEx関数を使用してみてください。以下は、このためのサンプルコードです。ただし、LARGE_INTEGERユニオンからサイズを取得する必要があります。

#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;
}
于 2013-03-19T10:54:18.480 に答える