【问题标题】:Obtain recursive filename with boost library使用 boost 库获取递归文件名
【发布时间】:2023-03-04 17:04:01
【问题描述】:

我尝试使用以下函数递归获取文件名。但我只有一个子文件夹名称(例如:/media/username)。为了理解这个问题,我将路径值写入/media/username 而不是/media,但这次我无法获得任何文件名。 /media 目录有特殊规定吗?如果是,我该如何克服?如果没有,为什么我不能得到文件名?

获取函数如下:

void obtain_filenames()
{
    for(const auto& p : fs::recursive_directory_iterator("/media"))
        m_filenames.push_back(p.path().string());
}

【问题讨论】:

    标签: boost filenames


    【解决方案1】:

    没有特别的规定。你要求文件名,所以你得到它们。如果你想要完整的路径,你可以这样做:

    for(const auto& p : fs::recursive_directory_iterator(directory))
        paths.push_back(fs::absolute(p.path()));
    

    请注意,这会为您提供整个路径(因此,如果您使用“.”,您可能会得到“/home/purgoufr/.bashrc”,而不是“./bashrc”)。如果你不想这样,请查看 `make_relative",例如:

        paths.push_back(directory / fs::relative(p.path(), directory));
    

    旁注:

    • 请记住,权限错误可能会破坏您的迭代器循环(请参阅fs::directory_options::pop_on_error
    • 以递归方式盲目地迭代任何目录可能会导致(安全)问题。在这种情况下,您可能会耗尽内存,导致无限循环(请参阅fs::directory_options::follow_directory_symlink)等。

    演示

    展示一些提到的改进和更多:

    Live On Coliru

    #include <boost/filesystem.hpp>
    
    namespace fs = boost::filesystem;
    using Paths = std::vector<fs::path>;
    
    Paths obtain_filenames(fs::path base, size_t max)
    {
        Paths paths;
        for(const auto& p : fs::recursive_directory_iterator(base, fs::directory_options::pop_on_error))
        {
            // paths.push_back(fs::absolute(p.path().string()));
            paths.push_back(base / fs::relative(p.path(), base));
            if (paths.size() >= max)
                break;
        }
    
        return paths;
    }
    
    #include <iostream>
    int main(int argc, char** argv) {
        for (auto arg : std::vector(argv + 1, argv + argc)) {
            for (auto const& path : obtain_filenames(arg, 5)) {
                std::cout << path << "\n";
            }
        }
    }
    

    例如在我的系统打印上使用 './sotest ../stackoverflow/*/' 运行时

    "../stackoverflow/asio/CMakeLists.txt"
    "../stackoverflow/asio/Service.h"
    "../stackoverflow/asio/Acceptor.cpp"
    "../stackoverflow/asio/main.cpp"
    "../stackoverflow/asio/Service.cpp"
    "../stackoverflow/boost-dll-example/.devcontainer"
    "../stackoverflow/boost-dll-example/.devcontainer/devcontainer.json"
    "../stackoverflow/boost-dll-example/.devcontainer/Dockerfile"
    "../stackoverflow/boost-dll-example/.git"
    "../stackoverflow/boost-dll-example/.git/info"
    "../stackoverflow/bucket/5f7d8fe7-be61-4182-9553-8aa4dceefd36"
    "../stackoverflow/bucket/5f7d8fe7-be61-4182-9553-8aa4dceefd36/q.png"
    "../stackoverflow/bucket/59caf141-803d-41dc-b7b0-fd6601e88295"
    "../stackoverflow/bucket/0605ef7a-0bcf-4b00-a3fe-ef2560758008"
    "../stackoverflow/bucket/718b317d-bc98-4012-a2c9-d1453edf7771"
    "../stackoverflow/CMakeFiles/CMakeRuleHashes.txt"
    "../stackoverflow/CMakeFiles/sotest.dir"
    "../stackoverflow/CMakeFiles/sotest.dir/CXX.includecache"
    "../stackoverflow/CMakeFiles/sotest.dir/depend.make"
    "../stackoverflow/CMakeFiles/sotest.dir/DependInfo.cmake"
    "../stackoverflow/cppcoro/args.cake"
    "../stackoverflow/cppcoro/.clang-format"
    "../stackoverflow/cppcoro/config.cake"
    "../stackoverflow/cppcoro/.git"
    "../stackoverflow/cppcoro/.git/hooks"
    "../stackoverflow/cpp-sort/build"
    "../stackoverflow/cpp-sort/build/cmake_install.cmake"
    "../stackoverflow/cpp-sort/build/compile_commands.json"
    "../stackoverflow/cpp-sort/build/Catch2-build"
    "../stackoverflow/cpp-sort/build/Catch2-build/CTestTestfile.cmake"
    "../stackoverflow/detail/yield.hpp"
    "../stackoverflow/eos-portable-archive/readme"
    "../stackoverflow/eos-portable-archive/change_log.txt"
    "../stackoverflow/eos-portable-archive/tutorial"
    "../stackoverflow/eos-portable-archive/tutorial/code"
    "../stackoverflow/eos-portable-archive/tutorial/code/tutorial_pba_10b.cpp"
    "../stackoverflow/eventpp/.gitignore"
    "../stackoverflow/eventpp/license"
    "../stackoverflow/eventpp/.github"
    "../stackoverflow/eventpp/.github/workflows"
    "../stackoverflow/eventpp/.github/workflows/main.yml"
    "../stackoverflow/fmt/cmake_install.cmake"
    "../stackoverflow/fmt/support"
    "../stackoverflow/fmt/support/rtd"
    "../stackoverflow/fmt/support/rtd/theme"
    "../stackoverflow/fmt/support/rtd/theme/theme.conf"
    "../stackoverflow/msghub/build"
    "../stackoverflow/msghub/build/compile_commands.json"
    "../stackoverflow/msghub/build/examples"
    "../stackoverflow/msghub/build/examples/cmake_install.cmake"
    "../stackoverflow/msghub/build/examples/server"
    "../stackoverflow/mymsg/.git"
    "../stackoverflow/mymsg/.git/hooks"
    "../stackoverflow/mymsg/.git/hooks/applypatch-msg.sample"
    "../stackoverflow/mymsg/.git/hooks/pre-rebase.sample"
    "../stackoverflow/mymsg/.git/hooks/pre-applypatch.sample"
    "../stackoverflow/mysql/.gitignore"
    "../stackoverflow/mysql/Jamfile"
    "../stackoverflow/mysql/tools"
    "../stackoverflow/mysql/tools/user_project_find_package"
    "../stackoverflow/mysql/tools/user_project_find_package/CMakeLists.txt"
    "../stackoverflow/networking-ts-impl/.git"
    "../stackoverflow/networking-ts-impl/.git/logs"
    "../stackoverflow/networking-ts-impl/.git/logs/HEAD"
    "../stackoverflow/networking-ts-impl/.git/logs/refs"
    "../stackoverflow/networking-ts-impl/.git/logs/refs/remotes"
    "../stackoverflow/nghttp2/Makefile.am"
    "../stackoverflow/nghttp2/makemanpages"
    "../stackoverflow/nghttp2/help2rst.py"
    "../stackoverflow/nghttp2/fedora"
    "../stackoverflow/nghttp2/fedora/spdylay.spec"
    "../stackoverflow/obj/testera.o"
    "../stackoverflow/obj/testerb.o"
    "../stackoverflow/pfr/meta"
    "../stackoverflow/pfr/meta/libraries.json"
    "../stackoverflow/pfr/test"
    "../stackoverflow/pfr/test/compile-fail"
    "../stackoverflow/pfr/test/compile-fail/non_aggregate.cpp"
    ... and so on
    

    【讨论】:

    • 添加了一个现场演示,其中包含一些提到的修复和有用的示例输出。 make_relative 调用可以改进错误处理,但我把它留给读者作为练习。
    • 我遇到了一个有趣的情况。可以肯定的是,我编译并运行了您发布的相同代码。但是同样的问题仍然存在,我的意思是,它只是返回了一个子文件夹名称。我多次运行我的文件,但结果没有改变。最后,我手动打开了磁盘文件(/media/username/..)并进入了子文件夹。当我在这一步之后运行它时,它开始看到所有子文件夹。
    • 虽然不明白为什么,手动打开目录后显示正常,但是插入磁盘后如果不手动打开,问题依旧。如果你有一个 linux 操作系统,你可以尝试运行你插入任何 U 盘后发送的代码,通过给出“/media”参数?
    • 哦。您可能错过了安装步骤。文件系统不会(总是)自动挂载。这与代码无关,所以我建议在 unix.stackechange.com 或 askubuntu.com 上询问/搜索
    猜你喜欢
    • 1970-01-01
    • 2018-05-15
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多