#include #include #include #include #include #include #include #include #include namespace fs = boost::filesystem; struct file_stats { size_t count; boost::int64_t size; file_stats () : count (0), size (0) {} friend std::ostream& operator<< (std::ostream& os, const file_stats& s) { os << s.count << " files, "; boost::int64_t divisor = 1 << 10; char units[] = "kMGTYFZ"; const char* unit = units; while (s.size > divisor << 10 && *(unit + 1)) { divisor <<= 10; ++unit; } return os << (double) s.size / divisor << ' ' << *unit << "iB"; } }; typedef std::map stat_map; void finder (const fs::path& root, stat_map& stats, bool recursive) { try { for (fs::directory_iterator iter (root), end; iter != end; ++iter) { if (fs::is_directory (iter->status ()) && recursive) finder (iter->path(), stats, recursive); else if (fs::is_regular (iter->status ())) { stat_map::iterator stat = stats.find (fs::extension (iter->path())); if (stat != stats.end()) { stat->second.count++; stat->second.size += fs::file_size (iter->path()); } } } } catch (std::exception& e) {} } int main (int argc, char** argv) { bool recursive = false; std::list roots; stat_map stats; for (int i = 1; i < argc; ++i) { if (strcmp (argv[i], "-R") == 0) recursive = true; else if (fs::is_directory (argv[i])) roots.push_back (argv[i]); else stats.insert (std::make_pair (argv[i], file_stats())); } if (stats.empty () || roots.empty ()) { std::cerr << "Usage: " << argv[0] << " [-R] directory [directory ...] " << "extension [extension ...]\n"; exit (1); } for (std::list::const_iterator iter = roots.begin(), end = roots.end(); iter != end; ++iter) { finder (*iter, stats, recursive); } for (stat_map::const_iterator iter = stats.begin(), end = stats.end (); iter != end; ++iter) std::cout << iter->first << ": " << iter->second << '\n'; return 0; }