龙空技术网

C++ 列出目录中的文件

启辰8 65

前言:

现时咱们对“列举当前目录下文件命令”大致比较注意,大家都需要了解一些“列举当前目录下文件命令”的相关文章。那么小编也在网摘上汇集了一些有关“列举当前目录下文件命令””的相关内容,希望小伙伴们能喜欢,兄弟们一起来学习一下吧!

文件系统库提供了一个directory_entry类,该类包含有关给定路径的目录相关信息。我们可以使用它来创建有用的目录列表。

如何做……

在本示例中,我们将使用directory_entry类中的信息创建一个目录列表实用程序:

我们首先定义我们的命名空间别名和用于显示路径对象的formatter专门化:

namespace fs = std::filesystem;    template<>  struct std::formatter<fs::path>: std::formatter<std::string> {      template<typename FormatContext>      auto format(const fs::path& p, FormatContext& ctx) {          return format_to(ctx.out(), "{}", p.string());      }  };

directory_iterator类使列出目录变得容易:

int main() {      constexpr const char* fn{ "." };      const fs::path fp{fn};      for(const auto& de : fs::directory_iterator{fp}) {          cout << format("{} ", de.path().filename());      }      cout << '\n';  }

输出:

chrono Makefile include chrono.cpp working formatter testdir formatter.cpp working.cpp

我们可以添加命令行选项来使其工作,就像Unix的ls命令一样:

int main(const int argc, const char** argv) {      // ... 使用argv设置fp,并检查路径是否存在 ...        if(is_directory(fp)) {          for(const auto& de : fs::directory_iterator{fp}) {              cout << format("{} ", de.path().filename());          }      } else {          cout << format("{} ", fp.filename());      }      cout << '\n';  }

如果我们想要输出排序,我们可以将directory_entry对象存储在一个可排序的容器中。

为了简化代码,我们可以为fs::directory_entry创建一个别名,并在main()的顶部声明一个de对象的vector。然后,在is_directory()块中,我们加载vector,对其进行排序,然后显示它。

如果我们想要不区分大小写的排序,我们需要一个比较函数来忽略大小写。我们可以编写一个函数来返回小写字符串,并在排序时使用它。

我们还可以创建一个print_dir()函数,以收集更多信息并以Unix ls命令的风格格式化输出。

最终,我们的输出可能如下所示:

-rwxr-xr-x   284K chrono*  -rw-r--r--     2K chrono.cpp  -rwxr-xr-x   178K formatter*  -rw-r--r--   906B formatter.cpp  lrwxr-xr-x     0B include -> /Users/billw/include  -rw-r--r--   642B Makefile  drwxr-xr-x     0B testdir/  -rwxr-xr-x   197K working*  -rw-r--r--     5K working.cpp

注意:这个实用程序是为POSIX系统(如Linux和macOS)设计的。它在Windows系统上也能工作,但Windows权限系统与POSIX系统不同。在Windows上,权限位将始终显示为完全设置。

它是如何工作的……

文件系统库通过其directory_entry和相关类携带丰富的信息。我们在这个示例中使用的主要类包括:

- path类:根据目标系统的规则表示文件系统路径。path对象由字符串或另一个path构造。它不必表示现有路径,甚至可能不是一个可能的路径。路径字符串被解析为组件部分,包括根名称、根目录和可选的一系列文件名和目录分隔符。

- directory_entry类:将path对象作为成员携带,并可能还存储其他属性,包括硬链接计数、状态、符号链接、文件大小和最后写入时间。

- file_status类:携带有关文件类型和权限的信息。perms对象可能是file_status的成员,表示文件的权限结构。

还有更多……

我本来打算在目录列表中包括每个文件的最后写入时间。

directory_entry类有一个成员函数last_write_time(),它返回一个表示文件最后写入时间的file_time_type对象。

不幸的是,在撰写本文时,可用的实现缺乏将file_time_type对象转换为标准chrono::sys_time的可移植方法,后者适合与cout或format()一起使用。

目前,这里有一个适用于GCC的解决方案:

string time_string(const fs::directory_entry& dir) {      using std::chrono::file_clock;      auto file_time{ dir.last_write_time() };      return format("{:%F %T}", file_clock::to_sys(dir.last_write_time()));  }

建议用户代码应使用std::chrono::clock_cast而不是file::clock::to_sys来在时钟之间转换时间点。不幸的是,目前没有可用的实现具有用于此目的的std::chrono::clock_cast特化。

使用这个time_string()函数,我们可以将其添加到print_dir()中,并修改格式字符串以包含时间戳。这样,我们的输出将包括每个文件的最后写入时间。

标签: #列举当前目录下文件命令