2012-06-07 61 views
17

我有這樣的Java的樹從路徑列表代表的文件系統(文件/目錄)

/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 
從路徑(蜇傷)這個名單

所以路徑列表,我需要克里特島一個Java樹結構有文件夾作爲葉節點和文件(不會是空的文件夾葉)。

我需要的是我添加的方法,我傳遞給他們一個字符串(文件的路徑),並將它添加到樹的正確位置創建正確的節點(文件夾),如果他們不在那裏

這種樹形結構需要我獲得節點列表,當我在節點和葉子的名單(但我認爲這將是樹木正常功能)

我會永遠字符串作爲路徑,而不是真實的文件或文件夾。 是否有東西準備好使用或源代碼開始?

非常感謝。

+0

* 「的源代碼開始?」 *參見[文件瀏覽器的GUI(http://codereview.stackexchange.com /問題/ 4446 /文件瀏覽器的GUI)。 –

+0

**另請參閱:** http://stackoverflow.com/questions/1005551/construct-a-tree-structure-from-list-of-string-paths – dreftymac

回答

21

謝謝你所有的答案。我做了我的工作實施。 我認爲我需要改進它,以便在向樹結構添加元素時使用更多緩存更好地工作。

正如我所說的,我所需要的是一種結構,它允許我對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; 
    } 


} 

測試。Java進行測試代碼

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

} 

請告訴我,如果你有關於改進措施一些好的建議:)

+0

我認爲改進它的一個好方法是添加一個簡單的方法來遍歷樹。除此之外,很好的工作 – user489041

+0

代碼的好例子! – 23ars

-1

看看新的Java 7 - nio2 package。所有你需要的是在裏面。

+0

這是有用的,但不需要一個文本列表路徑作爲輸入,如果你真的想要導航實際的文件系統,這很好。但在我的情況下,我想將我的虛擬文件系統(抽象數據庫)緩存在txt文件中。 –

1

我會推薦閱讀data structures,特別是trees。在Java中,您可以通過創建具有對其他節點的引用的節點類來表示這些節點。例如:

public class Node { 
    private Node[] children; 
    /* snip other fields */ 
    public boolean isFile() { 
     return children.count == 0; 
    } 
} 

顯然,您可以隨心所欲地存儲您的節點引用 - 數組或集合將與非二進制樹一起工作。

鑑於您的文件列表,您可以閱讀這些文件並填充樹結構。

2

好像你可以修改Trie/Radix TrieBinary Search Tree在任何情況下工作。你可以增加一個Trie來存儲「文件夾」作爲內部節點(而不是像普通Trie中的字符),或者你可以增加一個二叉搜索樹來將「文件夾」存儲爲內部節點(只要它們實現了可比較的接口)和「文件」作爲葉節點。

我在上面的文本中鏈接了這些結構的實現。

0

我實現了一個解決方案來挑戰自己,這是available as a GitHubGist

我代表DirectoryNode中文件系統層次結構的每個節點。輔助方法createDirectoryTree(String [] filesystemList)創建一個direcotry-tree。

以下是使用示例,其中包含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); 

的System.out.println -output是:

{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=[]}]}]}