#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <iostream>
#include <string>
#include <vector>
static const int SIZE_UNIT_NUM = 5;
struct file_info {
file_info(const std::string &str) : file_name(str) {
total_size = 0;
detail_size.resize(SIZE_UNIT_NUM, 0);
}
inline void show_info() const {
std::cout << "file name = " << file_name << " size = " << total_size << "B" << " detail size:" << detail_size[4] << "T" << detail_size[3] << "G" << detail_size[2] << "M" << detail_size[1] << "K" << detail_size[0] << "B" << std::endl;
}
std::string file_name;
size_t total_size;
std::vector<size_t>detail_size; // Byte KB MB GB TB
};
class file_system {
public:
file_system() = default;
file_system(const file_system &) = delete;
file_system & operator = (const file_system &) = delete;
~file_system() = default;
public:
void stat_file_info(const char *dir_path) {
get_file_info(dir_path);
for (const auto &info : file_info_set_) {
total_size_ += info.total_size;
info.show_info();
}
file_info fileinfo(dir_path);
stat_file_size(fileinfo, total_size_);
fileinfo.show_info();
}
size_t get_total_dir_size() const {
return total_size_;
}
private:
void stat_file_size(file_info &fileinfo, size_t bytes) {
fileinfo.total_size = bytes;
for (auto i = 0;i < SIZE_UNIT_NUM;i++) {
auto x = bytes / 1024;
auto y = bytes % 1024;
fileinfo.detail_size[i] = y;
if (0 == x) {
break;
}
bytes = x;
}
}
void get_file_info(const char *dir_path) {
DIR *dirp = nullptr;
struct stat stat_buf;
dirp = ::opendir(dir_path);
if (nullptr == dirp) {
std::cerr << dir_path << " opendir failed." << std::endl;
::exit(-1);
}
::chdir(dir_path);
struct dirent *entry = nullptr;
while (nullptr != (entry = readdir(dirp))) {
::lstat(entry->d_name, &stat_buf);
if (!S_ISDIR(stat_buf.st_mode)) {
file_info fileinfo(entry->d_name);
stat_file_size(fileinfo, stat_buf.st_size);
file_info_set_.emplace_back(fileinfo);
continue;
}
if (0 == strcmp(entry->d_name, ".") || 0 == strcmp(entry->d_name, "..")) {
continue;
}
file_info fileinfo(entry->d_name);
stat_file_size(fileinfo, stat_buf.st_size);
file_info_set_.emplace_back(fileinfo);
get_file_info(entry->d_name);
}
::chdir("..");
::closedir(dirp);
}
private:
size_t total_size_ = 0;
std::vector<file_info>file_info_set_;
};
int main() {
file_system filesystem;
filesystem.stat_file_info("/home/bwang/test1");
return 0;
}