Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing a directory structure in Java

I have to parse a set of directories given in the following text file:

# 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

The above file, depicts the directory structure this way:

A
|
+ B
|
+ C
| |
| + D
| |
| + E
| |
| + F
| | |
| | + G

Assuming the lines starting with # are comments, I have the following code right now:

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 + ".");
    }
}

So, this just does the work of displaying the directories, that too not in a hierarchical way to parse them. It just gives an output of textual representation, this way:

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.

If it was PHP, I can convert it to JSON nodes and can parse the parent or sibling, in a hierarchical way, but I am not sure how am I supposed to make this in Java. Any heads up will be great for me.

For now, I created a class for the tree structure this way:

public class Directory {
    private String name;
    private Directory parent;
}

But I am not sure how do I link the directories as kind of linked lists in the main Java program. Any help here would be appreciated. So, when I do some kind of tree structure here, I would like to achieve something like a directory traversing program.

Say, if I give the input as DirectoryParser C, then, it should output me something like:

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

Is this possible with the current approach of mine? Can someone please guide me in how to achieve this? Thanks in advance.

Disclaimer: I went through Java tree data-structure?, but I am supposed to get something simple in a single file without using any external plugins. :(

like image 890
Praveen Kumar Purushothaman Avatar asked Oct 21 '22 13:10

Praveen Kumar Purushothaman


1 Answers

Assuming all referenced parent directories are directories that have already been listed on previous lines you could create your directory tree in one pass. Put each directory you create in a map. Then once you create a new directory search for the parent directory in that map.

So feed each line to something like this:

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));
    }
}

where Directory is:

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 ...
}

Notes:

  • if aforementioned order is not there you may achieve the same goal in two passes. One pass to get all the directories and the second to set all the parents.
  • this assumes a \w+,\w+ format and unique directory names
  • you can use toString to generate your tree
like image 171
Lodewijk Bogaards Avatar answered Nov 03 '22 02:11

Lodewijk Bogaards