To do this you are going to have to read the file info into a data structure (like a std::vector
) and then sort the file info according to their size.
The old fashioned way could go something like this:
DIR* drstrm = opendir(".");
if(drstrm == NULL)
throw std::runtime_error(std::strerror(errno));
struct stat st; // this is to use decltype
// keep info from dirent & stat in one place
struct file_info
{
std::string name;
decltype(st.st_size) size;
};
// store list of files here to be sorted
std::vector<file_info> files;
while(dirent* entry = readdir(drstrm))
{
// get file info
if(::stat(entry->d_name, &st) == -1)
throw std::runtime_error(std::strerror(errno));
// is it a regular file?
if(!S_ISREG(st.st_mode))
continue;
// store it ready for sorting
files.push_back({entry->d_name, st.st_size});
}
// sort the file_info objects according to size
std::sort(std::begin(files), std::end(files), [](file_info const& a, file_info const& b){
return a.size < b.size;
});
// print them out
for(auto const& file: files)
std::cout << file.name << ": " << file.size << '\n';
Fortunately in newer versions of C++
(C++17
) you can use the new <filesystem>
standard library:
namespace fs = std::filesystem; // for brevity
std::vector<fs::path> files;
for(auto const& ent: fs::directory_iterator("."))
{
if(!fs::is_regular_file(ent))
continue;
files.push_back(ent);
}
std::sort(std::begin(files), std::end(files), [](fs::path const& a, fs::path const& b){
return fs::file_size(a) < fs::file_size(b);
});
for(auto const& file: files)
std::cout << file << ": " << fs::file_size(file) << '\n';