Directory size (via boost::filesystem) problem
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
Daniel Wyatt wrote:
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?
No, unsigned long is just 32 bits, it is not enough.
Do i need to use an unsigned long long or is there something else wrong here???
Yes, you should use a 64 bit integer. PS: Boost.Filesystem has a recursive_directory_iterator, it is very good for such directory iteration job. cg
Okay so it actually was that the unsigned long's maximum was reached. I didn't actually think about that until the last second. Unsigned long long is plenty though.
participants (3)
-
Daniel Wyatt
-
Daniel Wyatt
-
gchen