I've a list of paths like this
/mnt/sdcard/folder1/a/b/file1 /mnt/sdcard/folder1/a/b/file2 /mnt/sdcard/folder1/a/b/file3 /mnt/sdcard/folder1/a/b/file4 /mnt/sdcard/folder1/a/b/file5 /mnt/sdcard/folder1/e/c/file6 /mnt/sdcard/folder2/d/file7 /mnt/sdcard/folder2/d/file8 /mnt/sdcard/file9
So from this list of paths (Stings) I need to crete a Java Tree structure that has folders as nodes and files as leaf (there wont be empty folders as leaf).
What I need I think is the add method where I pass to them a String (path of the file) and it add it to the correct place in the tree creating correct nodes (Folder) if they are not already there
This tree structure will need me to get list of nodes when I'm on node and list of leafs (but I think this will be a normal features for trees)
I will always have Strings as paths and not real file or folders. Is there something ready to use or a source code to start?
Thank you very much.
Thank you for all your answer. I made my working implementation. I think that I will need to improve it in order to make it works better with more caching in adding element to the tree structure.
As I said what I was needing was a structure that allow me to have a "virtual" rappresentation of a FS.
MXMTree.java
public class MXMTree { MXMNode root; MXMNode commonRoot; public MXMTree( MXMNode root ) { this.root = root; commonRoot = null; } public void addElement( String elementValue ) { String[] list = elementValue.split("/"); // latest element of the list is the filename.extrension root.addElement(root.incrementalPath, list); } public void printTree() { //I move the tree common root to the current common root because I don't mind about initial folder //that has only 1 child (and no leaf) getCommonRoot(); commonRoot.printNode(0); } public MXMNode getCommonRoot() { if ( commonRoot != null) return commonRoot; else { MXMNode current = root; while ( current.leafs.size() <= 0 ) { current = current.childs.get(0); } commonRoot = current; return commonRoot; } } }
MXMNode.java
import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class MXMNode { List<MXMNode> childs; List<MXMNode> leafs; String data; String incrementalPath; public MXMNode( String nodeValue, String incrementalPath ) { childs = new ArrayList<MXMNode>(); leafs = new ArrayList<MXMNode>(); data = nodeValue; this. incrementalPath = incrementalPath; } public boolean isLeaf() { return childs.isEmpty() && leafs.isEmpty(); } public void addElement(String currentPath, String[] list) { //Avoid first element that can be an empty string if you split a string that has a starting slash as /sd/card/ while( list[0] == null || list[0].equals("") ) list = Arrays.copyOfRange(list, 1, list.length); MXMNode currentChild = new MXMNode(list[0], currentPath+"/"+list[0]); if ( list.length == 1 ) { leafs.add( currentChild ); return; } else { int index = childs.indexOf( currentChild ); if ( index == -1 ) { childs.add( currentChild ); currentChild.addElement(currentChild.incrementalPath, Arrays.copyOfRange(list, 1, list.length)); } else { MXMNode nextChild = childs.get(index); nextChild.addElement(currentChild.incrementalPath, Arrays.copyOfRange(list, 1, list.length)); } } } @Override public boolean equals(Object obj) { MXMNode cmpObj = (MXMNode)obj; return incrementalPath.equals( cmpObj.incrementalPath ) && data.equals( cmpObj.data ); } public void printNode( int increment ) { for (int i = 0; i < increment; i++) { System.out.print(" "); } System.out.println(incrementalPath + (isLeaf() ? " -> " + data : "") ); for( MXMNode n: childs) n.printNode(increment+2); for( MXMNode n: leafs) n.printNode(increment+2); } @Override public String toString() { return data; } }
Test.java for test code
public class Test { /** * @param args */ public static void main(String[] args) { String slist[] = new String[] { "/mnt/sdcard/folder1/a/b/file1.file", "/mnt/sdcard/folder1/a/b/file2.file", "/mnt/sdcard/folder1/a/b/file3.file", "/mnt/sdcard/folder1/a/b/file4.file", "/mnt/sdcard/folder1/a/b/file5.file", "/mnt/sdcard/folder1/e/c/file6.file", "/mnt/sdcard/folder2/d/file7.file", "/mnt/sdcard/folder2/d/file8.file", "/mnt/sdcard/file9.file" }; MXMTree tree = new MXMTree(new MXMNode("root", "root")); for (String data : slist) { tree.addElement(data); } tree.printTree(); } }
Please tell me if you have some good advice about improvments :)
I implemented a solution to the challenge myself, it is available as a GitHubGist.
I am representing each node of a filesystem-hierarchy in a DirectoryNode. A helper-method createDirectoryTree(String[] filesystemList) creates a direcotry-tree.
Here is the usage example, which is included in the GitHubGist.
final String[] list = new String[]{ "/mnt/sdcard/folder1/a/b/file1.file", "/mnt/sdcard/folder1/a/b/file2.file", "/mnt/sdcard/folder1/a/b/file3.file", "/mnt/sdcard/folder1/a/b/file4.file", "/mnt/sdcard/folder1/a/b/file5.file", "/mnt/sdcard/folder1/e/c/file6.file", "/mnt/sdcard/folder2/d/file7.file", "/mnt/sdcard/folder2/d/file8.file", "/mnt/sdcard/file9.file" }; final DirectoryNode directoryRootNode = createDirectoryTree(list); System.out.println(directoryRootNode);
The System.out.println -output is:
{value='mnt', children=[{value='sdcard', children=[{value='folder1', children=[{value='a', children=[{value='b', children=[{value='file1.file', children=[]}, {value='file2.file', children=[]}, {value='file3.file', children=[]}, {value='file4.file', children=[]}, {value='file5.file', children=[]}]}]}, {value='e', children=[{value='c', children=[{value='file6.file', children=[]}]}]}]}, {value='folder2', children=[{value='d', children=[{value='file7.file', children=[]}, {value='file8.file', children=[]}]}]}, {value='file9.file', children=[]}]}]}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With