Использование std :: filesystem с linux плохо или дерево файловой системы недоступно? - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь распечатать дерево каталогов моей системы, но при использовании root или где-то рядом с ним программа выдает исключение, например:

terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
  what():  filesystem error: status: Too many levels of symbolic links [/home/asmmo/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0]

И на используя сам root, программа выдает

terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
  what():  filesystem error: status: Too many levels of symbolic links [/sys/kernel/software_nodes/node2/dw-apb-uart.2/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1/firmware_node/physical_node1]

Код, который я использовал:

#include<iostream>
#include<filesystem>
#include<fstream>


void processPth(const std::filesystem::path&, std::ostream& = std::cout, const size_t& =0);

int main() {

    std::filesystem::path p{LR"(/home/asmmo)"};//or p{LR"(/)"} for the root
    std::ofstream myFile{"tree.txt"};
    processPth(p, myFile);

}




void processPth(const std::filesystem::path & p, std::ostream& ostream , const size_t& level ){
    if(!std::filesystem::exists(p)) return;//base case

    if(std::filesystem::is_regular_file(p))
        ostream<<std::string(2*level, ' ')<<"File: "<< p.filename()<<"\tSize: "<<std::filesystem::directory_entry(p).file_size()<<"\n";
    else if(std::filesystem::is_directory(p))
    {
        ostream<<std::string(2*level, ' ')<<"Directory: "<< p.filename()<<"\n";
        for(const auto& it : std::filesystem::directory_iterator(p))
            processPth( it, ostream, level+1);
    }


}

Я попытался достичь этих v0, используя терминал, и результат был следующим:

asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0/v0$ cd v0
asmmo@asmmo:~/.local/share/webkitgtk/databases/indexeddb/v0/v0/v0/v0/v0/v0/v0/v0

Когда я пытаюсь распечатать дерево для некоторого ближайшего каталога (как в следующем коде), он работает нормально.

int main() {

    std::filesystem::path p {std::filesystem::current_path()};
    std::ofstream myFile{"tree.txt"};
    processPth(p, myFile);

}

1 Ответ

1 голос
/ 25 февраля 2020

Если в вашей файловой системе есть символическая ссылка, которая ссылается на один из ее родительских каталогов, то рекурсивный поиск в этом каталоге приведет к бесконечной рекурсии, потому что символическая ссылка продолжит возвращать вас в родительский каталог.

Система допускает только очень много рекурсий и возвращает ошибку, если вы рекурсивны слишком глубоко.

Вы, вероятно, должны игнорировать символические ссылки при рекурсивной итерации по такому каталогу. Вы можете использовать std::filesystem::is_symlink, чтобы проверить, является ли путь символической ссылкой.

...