在Java中解析目录结构

5

我需要解析一个文本文件中给出的一组目录:

# Note: The root folder's parent is labelled as "?"
#       Assume all directory has different name
#
A,?
B,A
C,A
D,C
E,C
F,C
G,F

上述文件按照以下方式描述了目录结构:
A
|
+ B
|
+ C
| |
| + D
| |
| + E
| |
| + F
| | |
| | + G

假设以 # 开头的行是注释,现在我有以下代码:
String line;
BufferedReader f = new BufferedReader(new FileReader(new File("directory.txt")));
while ((line = f.readLine()) != null)
{
    if (!line.substring(0, 1).equals("#"))
    {
        String directory, parent;
        directory = line.split(",")[0];
        parent = line.split(",")[1];
        if (parent.equals("?"))
            System.out.println("Directory " + directory + " is the root.");
        else
            System.out.println("Directory " + directory + " found inside " + parent + ".");
    }
}

所以,这只是显示目录的工作,而且不是以分层方式解析它们。它只提供文本表示的输出,如下所示:
Directory A is the root.
Directory B found inside A.
Directory C found inside A.
Directory D found inside C.
Directory E found inside C.
Directory F found inside C.
Directory G found inside F.

如果是 PHP,我可以将它转换为 JSON 节点,并以分层的方式解析父节点或兄弟节点,但我不确定如何在 Java 中实现这一点。如果你能给我一些提示,那就太好了。
目前,我已经创建了一个树形结构的类,如下所示:
public class Directory {
    private String name;
    private Directory parent;
}

但是我不确定如何在主Java程序中将目录链接为链表形式。这里的任何帮助都将不胜感激。因此,当我在这里做某种树结构时,我想实现类似目录遍历程序的东西。

比如,如果我输入 DirectoryParser C,那么它应该输出:

C
|
+ D
|
+ E
|
+ F
| |
| + G

我的方式可行吗?请有经验的人指导我该如何实现?提前感谢。

免责声明:我已经阅读了Java树型数据结构?,但是我需要在一个单独的文件中获得简单的东西,而不使用任何外部插件。:(


你可以在Java中创建内部类,所以不要让1个文件的要求阻止你使用树——“Java树数据结构”问题中的第一个答案比你需要的更复杂。只需使用他的“Node”类,并将“T data”更改为“String name”,如果你不想/不需要泛型。 - Gus
2个回答

3
假设所有引用的父目录都是之前已经列出的目录,你可以一次性创建目录树。将每个新创建的目录放入一个映射表中。当你创建一个新目录时,在该映射表中查找其父目录即可。所以,将每行输入传输到以下类似的代码中:
public void parseLine(String line) {
    if (isComment.matcher(line).matches()) {
        return; // comment, skip line
    }

    Matcher m = dirPattern.matcher(line);
    if (!m.matches()) {
        throw new InvalidSyntaxException("line " + line + " does not follow dir syntax.");
    }

    String dirName = m.group(0);
    String parentDirName = m.group(1);
    if (parentDirName == "?") {
        directories.put(dirName, new Directory(dirName));
    } else {
        Directory parentDir = directories.get(parentDirName);
        if (parentDir == null) {
            throw new DirectoryNotFoundException("Directory " + parentDir + " not found");
        }
        directories.put(dirName, new Directory(dirName, parentDir));
    }
}

其中Directory是:

public class Directory {
    private String name;
    private Directory parent;
    private Set<Directory> children = new HashSet<Directory>();

    public Directory(String n) {
        this(n, null);
    }

    public Directory(String n, Directory p) {
        name = n;
        parent = p;
        if (parent != null) {
            parent.addChild(this);
        }
    }

    // keep private to ensure no child is set without a proper parent
    private void addChild(Directory child) {
        children.add(child);
    }

    @Override
    public String toString() {
        String str = name;
        for (Directory child : children) {
            str += child.toString();
        }
        return str;
    }
            .... be sure to implement equals and hashCode ...
}

注意事项:

  • 如果上述命令不存在,您可以通过两个步骤来达到同样的目标。第一次遍历获取所有的目录,第二次遍历设置所有的父目录。
  • 这假定目录名称采用“\w+,\w+”格式且唯一
  • 您可以使用toString方法生成您的树形结构

我正在尝试这个。 :) - Praveen Kumar Purushothaman
这种方法对我没有帮助,伙计。但还是谢谢你。我点了个赞。我会发布我所做的!谢谢。 - Praveen Kumar Purushothaman

0

好的,大家好,我使用了同样的方法。我使用一个Iterator遍历ArrayList, 并以如下方式使用:

static void RecursiveFolderFinder(String Root)
{
    Iterator<Folder> Folder = ListOfFolders.iterator();
    while (Folder.hasNext())
    {
        Folder curFolder = Folder.next();
        if (curFolder.getParent().equals(Root))
        {
            OutputList += " " + curFolder.getName() + " ";
            OutputList += "{";
            RecursiveFolderFinder(curFolder.getName());
            if (OutputList.substring(OutputList.length()-1, OutputList.length()).equals("{"))
                OutputList = OutputList.substring(0, OutputList.length()-1);
            else if (!OutputList.substring(OutputList.length()-1, OutputList.length()).equals(" "))
                OutputList += " }";
            else
                OutputList += "}";
        }
    }
}

我知道,这种字符串操作很疯狂且脆弱,我用它来确保没有其他人使用这样一个有趣的字符串!只是讽刺。感谢@mrhobo的回答。如果有人能建议我一个更好的输出,那就太棒了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接