Как получить самые большие файлы в текущем рабочем каталоге в Unix? - PullRequest
0 голосов
/ 05 апреля 2019

Я знаю, как получить список файлов в Unix.Программа на С ++, которую я попробовал, находится ниже.Теперь, как мне распечатать самые большие файлы в порядке убывания?

int main() {
    DIR* drstrm = opendir(".");

    if (drstrm == NULL) {
        perror("error opening directory");
        return 1;
    }

    struct dirent* directoryentry = readdir(drstrm);

    while (directoryentry != NULL) {
        cout << (*directoryentry).d_name << endl;
        directoryentry = readdir(drstrm);
    }

    return 0;
}

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

Поскольку вы сказали, что можете использовать C ++ 17, библиотека файловой системы, которую она представляет, делает это действительно простым (и переносимым на системы, которые не имеют opendir() / readdir()):

#include <iostream>
#include <vector>
#include <filesystem>
#include <algorithm>
#include <string>

int main(int argc, char **argv) {      
  if (argc != 2) {
    std::cerr << "Usage: " << argv[0] << " DIRECTORY\n";
    return 1;
  }

  std::vector<std::filesystem::directory_entry> files;

  for (const auto &dirent : std::filesystem::directory_iterator(argv[1])) {
    if (dirent.is_regular_file()) {
      files.push_back(dirent);
    }
  }

  std::sort(files.begin(), files.end(), [](const auto &a, const auto &b){
      return a.file_size() > b.file_size(); });

  for (const auto &dirent : files) {
    // Quotes the filenames
    // std::cout << dirent.path() << '\n';
    // Doesn't quote
    std::cout << static_cast<std::string>(dirent.path()) << '\n';
  }

  return 0;
}

Использование:

$ g++-8 -std=c++17 -O -Wall -Wextra test.cpp -lstdc++fs
$ ./a.out .
a.out
bigfile.txt
test.cpp
smallfile.txt
etc.

Если вы не можете использовать C ++ 17, остается тот же подход: поместите имена файлов и их размеры в вектор и выполните сортировку по размерам, используя >вместо обычного < (который будет сортироваться от наименьшего к наибольшему).В системах POSIX вы можете получить размер файла с помощью stat(2).

0 голосов
/ 05 апреля 2019

Для этого вам нужно будет прочитать информацию о файле в структуру данных (например, std::vector), а затем отсортировать информацию о файле в соответствии с их размером.

Старомодный путь может пойти примерно так:

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';

К счастью, в новых версиях C++ (C++17) вы можете использовать новую стандартную библиотеку <filesystem>:

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';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...