5

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. :(

1
  • you can create inner classes in java; so don't let the 1-file requirement stop you from using the tree -- that first answer in the "Java tree data-structure" question is more complicated than you need. Just use his "Node" class, and change "T data" to "String name" if you don't want/need generics Commented Mar 4, 2014 at 14:30

2 Answers 2

3

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
Sign up to request clarification or add additional context in comments.

2 Comments

I am trying this out. :)
This approach didn't help me buddy. But thanks. +1d you. I will be posting what I have done! Thanks.
0

OKay Guys, I approached the same old method for this. I used an Iterator to walk through the ArrayList and used it this way:

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

I know, this kind of string manipulation is crazy and weak, I used his for making sure, no one else uses such a funny one! Just sarcastic. Thanks for @mrhobo's answer. If anyone could suggest me a better output, awesome then!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.