others - 如何利用现代 C++11/C++14/C+1Z 编写UNIX文件系统"ls R/" 实用程序?

  显示原文与译文双语对照的内容
0 0

为了学习/理解现代 C++的各种概念,我尝试编写类似于"R/" which的类似程序,递归列出子目录。 为了达到这个目的,我使用了的未来 C++ 文件系统 库,这样程序可以。 到目前为止,我可以编写下面的程序来实现这个。

#include<filesystem>
//Other herader files
//Below typedef is for VS2013
using fspath = std::tr2::sys::path;
using dir_iterator = std::tr2::sys::directory_iterator;
using namespace std::tr2::sys;
struct directory {
 std::vector<fspath> files;
 std::vector<fspath> operator()(const fspath& input) {
 std::cout <<"Input Directory Name:" <<input.string() <<std::endl;
 dir_iterator bgnitr(input);
 dir_iterator enditr;
 for (dir_iterator itr = bgnitr; itr!= enditr; ++itr) {
//Only store the directory from input directory, 
//otherwise display the name
 fspath tmp = *itr;
 if (is_directory(tmp)) {
 files.push_back(tmp);
 }
 else {
 tmp = tmp.filename();
 std::cout <<tmp.string() <<std::endl;
 }
 }
 return files;
 }
};
int main(int argc, const char** argv) {
 fspath input{argv[1]};
 directory dir;
 auto files = dir(input);
 std::sort(std::begin(files), std::end(files));
 std::for_each(std::begin(files), std::end(files), directory());
 return 0;
}

上程序工作正常,如果我的输入目录的子目录为 ,那么产生预期结果。 我可以使用 "recursive_directory_iterator",但是它给出了输入目录中所有目录中所有文件的列表。

它不处理实际输入目录包含子目录本身包含子目录和文件的情况。 基本上这些级别可以达到由 UNIX"ls R"实用程序处理的任何级别。

问题

我想知道下一步处理目录中的hierarchy层次的方法是什么?

一般来说,当我们需要模型/设计类似的东西时,我们应该遵循什么样的方法,以英镑为代价来。 我有点意识到 "复合设计 Pattern"to可以用来建模这样的东西。 这个 Pattern 能被应用到这个特定的问题。 如果是,有人可以提供解释/评论?

我的主要目的是了解一般的准则,使用现代 C++ concepts/library/design concepts.Kindly 处理这些问题。

时间: 原作者:

0 0

我将重命名你的directory 类,它不模型一个目录,它是一个打印目录内容的函数。

你可以使用基于范围的for 循环和 directory_iterator 来简化语法:

for (auto f : fs::directory_iterator{dir})

程序假定只用引用目录的单个参数调用,而 ls -R 可以用文件或者目录的零个参数调用。

我可以这样做,尽管这可以能会改进 main 中的逻辑并将它的集成到 ls 函数中:

#include <utility>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
void ls(std::ostream& out, const fs::path& dir)
{
 std::vector<std::pair<std::string, bool>> files;
 for (auto f : fs::directory_iterator{dir})
 files.emplace_back(f.path().filename(), is_directory(f));
 std::sort(files.begin(), files.end());
//print directory contents
 out <<dir.string() <<":n";
 for (auto& f : files)
 out <<f.first <<'n';
 out <<std::endl;
//recurse into directories
 for (auto& f : files)
 if (f.second)
 ls(out, dir/f.first);
}
int main(int argc, char** argv)
{
 if (argc <2)
 ls(std::cout,".");
 else
 {
 std::vector<std::string> files;
 std::vector<std::string> dirs;
 for (int i = 1; i <argc; ++i)
 if (fs::is_directory(argv[i]))
 dirs.push_back(argv[i]);
 else
 files.push_back(argv[i]);
 std::sort(files.begin(), files.end());
 for (auto& f : files)
 std::cout <<f <<'n';
 std::cout <<'n';
 std::sort(dirs.begin(), dirs.end());
 for (auto& d : dirs)
 ls(std::cout, d);
 }
}
原作者:
...