【问题标题】:Structuring/organizing a linked list of filesystem folders结构化/组织文件系统文件夹的链接列表
【发布时间】:2018-03-30 05:29:50
【问题描述】:

TLDR

我需要知道如何使用链表来表示文件系统 结构,当节点遍历是在一个奇怪的反转深度优先时, 按字母顺序,一次只知道两件事:

  • 完整的文件(或文件夹)路径,以及:
  • 此节点是文件还是文件夹?


详情:

UE4 通过IPlatformFile 支持内置的跨平台文件系统操作。
对于文件系统遍历,它们包含以下方法:

我的目标是填写以下结构:

struct FFolderNode
{
public:
    FFolderNode() : FFolderNode(nullptr, TEXT(""), TEXT("")) {};
    FFolderNode(const FString& Path, const FString& Name) : FFolderNode(nullptr, Path, Name) {};
    FFolderNode(FFolderNode *ParentNode, const FString& Path, const FString& Name) : ParentNode(ParentNode), Path(Path), Name(Name)
    {
        ID = FGuid::NewGuid();
    };

    // Makes it easier to identify, map & find this node
    FGuid ID;
    // The name of this directory
    FString Name;
    // The path of this directory
    FString Path;
    // The filenames this directory contains
    TArray<FString> FileNames;
    // The upwards directory (equivalent to the path "..")
    FFolderNode *ParentNode;
    // The subfolders (if any) contained within this directory
    TArray<FFolderNode*> ChildNodes;
};


我遇到的问题...
我将项目的Contents 文件夹路径传递给IPlatformFile::IterateDirectory,它会这样做:

看起来像字母顺序?所以我不知道从哪里开始。
似乎我需要能够在创建和分配它们的父节点之前创建节点,并且没有任何真正的所有权先验知识,除了当前访问的节点是文件或文件夹,并且它是字符串的完整路径。

IPlatformFile::FDirectoryVisitor::VisitIterateDirectory 调用的递归函数...引擎源似乎创建了一个内联类,它继承了FDirectoryVisitor 并覆盖了这个方法,所以这就是我在代码中所做的:

FFolderNode UDSAssetManager::GetContentTree()
{
    static auto ContentPath = FPaths::ConvertRelativePathToFull(FPaths::GameContentDir());

    class FFolderVisitor : public IPlatformFile::FDirectoryVisitor
    {
    public:
        IPlatformFile& PlatformFile;

        FFolderVisitor(IPlatformFile& InPlatformFile) :
            PlatformFile(InPlatformFile), RootNode(nullptr), PreviousNode(nullptr),
            FolderDepth(-1), PreviousDepth(-1) {};

        FFolderNode *CreateRootNode(const FString& Path, const FString& Name)
        {
            VisitedNodes.Empty();
            if (RootNode != nullptr)
                delete RootNode; // TODO: Traverse entire tree, releasing memory for all child nodes

            TArray<FString> SubPath;
            Path.ParseIntoArray(SubPath, TEXT("/"));
            if (SubPath.Num() > 0 && SubPath[SubPath.Num() - 1] == Name)
                SubPath.RemoveAt(SubPath.Num() - 1);

            return RootNode = new FFolderNode(FString::Join(SubPath, TEXT("/")), Name);
        };

        virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory) override
        {
            auto Path = FString(FilenameOrDirectory);
            auto Result = PlatformFile.IterateDirectory(FilenameOrDirectory, *this);

            if (RootNode == nullptr)
                return false;

            FFolderNode *ThisNode = nullptr;
            if (VisitedNodes.Num() < 1)
                ThisNode = RootNode;
            else
                ThisNode = new FFolderNode();

            auto TempPath = Path.Replace(*ContentPath, TEXT(""));
            TArray<FString> PathArray;
            TempPath.ParseIntoArray(PathArray, TEXT("/"));
            FolderDepth = PathArray.Num();

            //
            // DO SOMETHING here, even though RootNode is NOT guaranteed
            // to be the actual root of the tree... ?
            //

            PreviousNode = ThisNode;
            PreviousDepth = FolderDepth;
            VisitedNodes.Add(ThisNode);

            return true;
        };

        FORCEINLINE FFolderNode GetRootNode() const {
            if (RootNode == nullptr)
                return FFolderNode();
            return *RootNode;
        };

    private:
        FFolderNode *RootNode;
        FFolderNode *PreviousNode;
        int32 FolderDepth;
        int32 PreviousDepth;
        TArray<FFolderNode*> VisitedNodes;
    };

    FFolderVisitor FolderList(FPlatformFileManager::Get().GetPlatformFile());
    auto RootNode = FolderList.CreateRootNode(ContentPath, TEXT("Content"));
    FolderList.PlatformFile.IterateDirectory(*ContentPath, FolderList);

    return *RootNode;
}

如何通过引擎遍历文件结构的方式正确构建链表?

【问题讨论】:

    标签: c++ tree directory unreal-engine4 graph-traversal


    【解决方案1】:

    FFolderVisitor::Visit 内部调用IterateDirectory 似乎实际上导致了奇怪的遍历顺序。在创建一个单独的方法来处理根节点的初始化并从那里调用IterateDirectory 之后,遍历以正确的 DFS 顺序发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多