Boost logo

Boost Users :

From: Daniel Wyatt (daniel.wyatt_at_[hidden])
Date: 2007-01-21 06:20:43


Okay so i just wrote this quick program to test boost::filesystem's
features out. It's supposed to find the size of a directory (the sum of
the size of the files in it) and optionally recurse all subdirectories:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <boost/filesystem/operations.hpp>

using namespace std;
using namespace boost::filesystem;

void Usage(char *Path)
{
    printf("Usage: %s <Directory> [-r]\n", Path);
    exit(EXIT_FAILURE);
}

unsigned long DirSize(const string Directory, bool Recurse = false)
{
    long Size = 0;
    directory_iterator itDir;
    directory_iterator itEnd;
    path Path;

    Path = Directory;
    itDir = directory_iterator(Path);
    for (; itDir != itEnd; itDir++)
    {
        if (is_directory(*itDir))
        {
            if (Recurse)
                Size += DirSize(itDir->string(), true);

            continue;
        }
        Size += file_size(*itDir);
    }
    return Size;
}

string UnitString(unsigned long Bytes)
{
    const char *Units[] = {"bytes", "KiB", "MiB", "GiB", "TiB", "PiB"};
    const unsigned int UnitsMax = 6;
    double Size = (double)Bytes;
    unsigned int i = 0;
    stringstream ss;

    for (i = 0; i < UnitsMax && Size >= 1024.0; i++)
        Size /= 1024.0;

    ss.precision(2);
    ss << fixed << Size;
    ss << " " << Units[i];
    return ss.str();
}

int main(int argc, char *argv[])
{
    bool Recurse = false;

    if (argc != 2 && argc != 3)
        Usage(argv[0]);

    if (argc == 3)
        Recurse = true;

    if (argc == 3 && stricmp(argv[2], "-r") != 0)
        Usage(argv[0]);

    if (!exists(argv[1]))
    {
        printf("Directory '%s' does not exist\n\n", argv[1]);
        Usage(argv[0]);
    }
    if (!is_directory(argv[1]))
    {
        printf("'%s' is not a directory\n\n", argv[1]);
        Usage(argv[0]);
    }
    printf("Size of directory '%s': %s\n", argv[1],
UnitString(DirSize(argv[1], Recurse)).c_str());
    return EXIT_SUCCESS;
}

Its not too pretty but ignore that please. It works for the most part.
It gives perfect results for nearly all directories. One exception i've
noticed on my system is "C:\Program Files". It gives me "419.15 MiB" but
it should be giving me something more like "8.40 GiB". I figure an
unsigned long is large enough, isn't it? Do i need to use an unsigned
long long or is there something else wrong here???

Thanks,
Daniel Wyatt


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net