如何在Unix当前工作目录中获取最大的文件?

时间:2019-04-05 00:07:37

标签: c++ unix

我知道如何获取Unix中的文件列表。我尝试过的C ++程序如下。现在如何按降序打印最大的文件?

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 个答案:

答案 0 :(得分:2)

自从您说可以使用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,则仍然可以使用相同的方法:将文件名及其大小放在矢量中,然后使用>而不是常规的{{1 }}(从最小到最大排序)。在POSIX系统上,您可以使用<获得文件大小。

答案 1 :(得分:0)

要执行此操作,您将必须将文件信息读入数据结构(如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';