17

Вопрос по c, windows, c++, winapi – Размер каталога [дубликат]

This question already has an answer here:

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

Есть ли способ получить размер каталога / размер папки без фактического обхода этого каталога и добавления размера каждого файла в нем? В идеале хотелось бы использовать некоторую библиотеку, такую как boost, но win api тоже подойдет.

Возможно нет. Вот почемуright-click -> Properties так долго бегать ...

от Mysticial

Research Effort, что является причиной номер один, если вы наведите указатель мыши на кнопку понижения. Простой поиск в Google предоставит множество "Вы должны пройти".

от Brian Roach

ИМХО, сам факт, что Windows Explorer явно выполняет обход, должен быть достаточно намеком.

от Seva Alekseyev

Я также не согласен с отрицательными голосами ... Это совершенно правильный вопрос.

от Mysticial

Я тоже не понимаю, почему это должно быть опущено. Это очень актуальный вопрос. Давайте, ребята. Слишком локализовано? В самом деле.

от Niklas B.
4 ответа
4

Я не думаю

что есть что-то подобное, по крайней мере, нет функции Win32 API.

Родной для окон:

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);

} 

Error: User Rate Limit Exceeded(uint64_t)(data.nFileSizeHigh * ((uint64_t)MAXDWORD + 1))

от 
14

Насколько я знаю

вы должны делать это с итерацией в большинстве операционных систем.

Вы можете взглянуть на boost.filesystem, у этой библиотеки есть recursive_directory_iterator, он будет перебирать любой файл в системе, получая накопительный размер.

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

PS: вы можете сделать это намного чище, используя std :: аккумулятор и лямбда, я просто CBA

Error: User Rate Limit Exceeded

от 

Error: User Rate Limit Exceeded

от 
2

Вы должны пройти через файлы. Получить правильный результат сложно

если в дереве есть жесткие ссылки или точки повторного анализа. Смотрите Рэймонда ЧенаСообщение блога для деталей.

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

Error: User Rate Limit ExceededIsBrowsePathError: User Rate Limit Exceeded

от 

Похожие вопросы