2012-04-04 12 views
15

क्या वास्तव में इस निर्देशिका को घुमाने और इसमें प्रत्येक फ़ाइल का आकार जोड़ने के बिना निर्देशिका आकार/फ़ोल्डर आकार प्राप्त करने का कोई तरीका है? आदर्श रूप से कुछ लाइब्रेरी जैसे बूस्ट का उपयोग करना चाहते हैं लेकिन जीत एपीआई भी ठीक रहेगा।एक निर्देशिका का आकार

+7

शायद नहीं। यही कारण है कि 'राइट-क्लिक करें -> गुणों को चलाने के लिए बहुत लंबा समय लगता है ... – Mysticial

+5

मुझे भी यह नहीं पता कि यह क्यों कम किया जाना चाहिए। यह एक बहुत ही वैध सवाल है। चलो दोस्तो। बहुत स्थानीयकृत? वास्तव में। –

+0

मैं डाउनवॉट्स से सहमत नहीं हूं ... यह एक पूरी तरह से वैध सवाल है। – Mysticial

उत्तर

10

जहां तक ​​मुझे पता है कि आपको इसे अधिकांश ऑपरेटिंग सिस्टम पर पुनरावृत्ति के साथ करना है।

आप boost.filesystem पर एक नज़र डाल सकते हैं, इस लाइब्रेरी में एक रिकर्सिव_डायरेक्टरी_इटरेटर है, फिर भी यह सिस्टम को फिर से जमा करने वाले सिस्टम पर फ़ाइल को फिर से चालू करेगा।

http://www.boost.org/doc/libs/1_49_0/libs/filesystem/v3/doc/reference.html#Class-recursive_directory_iterator

include <boost/filesystem.hpp> 
int main() 
{ 
    namespace bf=boost::filesystem; 
    size_t size=0; 
    for(bf::recursive_directory_iterator it("path"); 
     it!=bf::recursive_directory_iterator(); 
     ++it) 
    { 
     if(!bf::is_directory(*it)) 
      size+=bf::file_size(*it); 
    } 
} 

पुनश्च: आप इस एक बहुत क्लीनर एसटीडी का उपयोग करके कर सकते हैं :: जमा होते हैं और एक लैम्ब्डा मैं सिर्फ CBA

3

मुझे नहीं लगता कि ऐसा ही कुछ है, कम से कम है कोई win32 एपीआई समारोह नहीं।

खिड़कियों के लिए Natively:

void DirectoryInfo::CalculateSize(std::string _path) 
{ 
    WIN32_FIND_DATAA data; 
    HANDLE sh = NULL; 

    sh = FindFirstFileA((_path+"\\*").c_str(), &data); 

    if (sh == INVALID_HANDLE_VALUE) 
    { 
      return; 
    } 

    do 
    { 
     // skip current and parent 
     if (std::string(data.cFileName).compare(".") != 0 && std::string(data.cFileName).compare("..") != 0) 
     { 

      // if found object is ... 
      if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) 
      { 
       // directory, then search it recursievly 
       this->CalculateSize(_path+"\\"+data.cFileName); 


      } else 
      { 
       // otherwise get object size and add it to directory size 
       this->dirSize += (__int64) (data.nFileSizeHigh * (MAXDWORD) + data.nFileSizeLow); 
      } 
     } 

    } while (FindNextFileA(sh, &data)); // do 

    FindClose(sh); 

} 
+0

मुझे पूरा यकीन है कि हमें गुणा करने की आवश्यकता है (MAXDWORD + 1)। असाइन किए गए मानते हैं: '(uint64_t) (data.nFileSizeHigh * ((uint64_t) MAXDWORD + 1)) –

2

आप फ़ाइलों को पार करना होगा। सही परिणाम प्राप्त करना मुश्किल है यदि पेड़ में हार्ड-लिंक या रिपर्स पॉइंट हैं। विवरण के लिए रेमंड चेन के blog post देखें।

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

यह यूनिकोड का उपयोग करता है और रिटर्न dirs में विफल रहा है, तो आपको लगता है कि चाहते हैं।

उपयोग कॉल करने के लिए:

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

लेकिन कभी नहीं पारित size

+0

लगभग काम करता है, लेकिन 'IsBrowsePath'' फ़ंक्शन गायब है – ibell

संबंधित मुद्दे