Rekursive File Listing mit Abstrakten Datentyp

Das sind ziemliche Verrenkungen nur um diesen kleinen Baum auszugeben. Die Klasse File stellt bereits einen Knoten eines Baumes dar. Es kann Dir sowohl Parent als auch Childs zurückgeben und das ist alles was ein Knoten können muss.

Wenn Du das Dateisystem ausgeben willst bräuchtest Du nur folgendes:
Java:
    public static void main(String[] args) {
        listFiles(new File("/home/mahe"));
    }

    static void listFiles(File file) {
        listFiles(file, 0);
    }

    static void listFiles(File file, int in) {
        for (int i = 0; i < in; ++i) {
            System.out.print(" ");
        }
        System.out.println(file.getName());

        if (file.isDirectory() && file.canRead()) {
            ++in;
            for (File f : file.listFiles()) {
                listFiles(f,in);
            }
        }
    }

Achja, in einem Baum hat jeder Knoten nur ein Parent. Wäre das anders, wärs kein Baum.
 
Zuletzt bearbeitet:
Vielen Dank mahe für deinen Beitrag!

Deine Implementierung ist (soweit ich das beurteilen kann) eine normale rekursive Auflistung der Dateien (plus Unterordner und deren Dateien) und deren Ausgabe. Ich will dagegen die Datei-Hierarchie explizit speichern, umso später denn Pfad einer Datei (eines Knoten) wiedergeben zu können.

Mein Problem ist nun folgendes:
Ich kann zwar mit DefaultMutableTreeNode die Hierarchie eines Ordners wiedergeben, allerdings kann ich keine File-Objekte in dem Baum speichern. Komischerweise wird nur der Name gespeichert (bzw. der Pfad der Datei). Ein Zugriff auf
Java:
tree.getChildAt(i).getName()
funktioniert nicht. Auch wenn ich es Caste:
Java:
 ((File) tree.getchildAt(i)).getName()
klappt es nicht.

Hat jmd. eine Idee, wie ich Objekte vom Typ File in einem Baum speichern kann, um so auf die Methoden der Klasse File zugreifen zu können?
 
Zuletzt bearbeitet von einem Moderator:
Wenn Du in Deinem Code Zeile 19 so schreibst:
Java:
DefaultMutableTreeNode node = new DefaultMutableTreeNode(files[i]);
also ".getName()" weglässt speicherst Du das File-Objekt im TreeNode.

Bekommen tust Du das File-Objekt dann über die Methode "getUserObjekt".

Dein Ausschnitt würde dann so oder so ähnlich aussehen:
Java:
((File) ( (DefaultMutableTreeNode) tree.getChildAt(i) ).getUserObjekt() ).getName();
 
TreeNode ist wie in meinem Post gezeigt eine eigene Datenstruktur. Wenn du keinen JTree benutzen willst, dann benutze auch nicht dessen TreeNodes, sondern schreib es selber. Es ist ja wirklich nicht mehr als in dem Interface angegeben.

Wenn du mehrer Eltern haben willst, solltest du stattdessen einen Graphen nehmen:

Java:
public interface Node<T> {
 
   public Node<T> getParent();
   public List<Node<T>> getChildren();
   public T getData();
   public List<Edge<T>> getIncomingEdges();
   public List<Edge<T>> getOutgoingEdges();
 
}


Java:
public interface Edge<T> {
 
   public TreeNode<T> getIncomingNode();
   public TreeNode<T> getOutgoingNode();
 
}

Ein Graph besteht aus Knoten die über Kanten verbunden sind. Auch recht simpel.
 
Vielen Dank zeja!

Ich hab deinen dezenten Hinweis jetzt (endlich) verstanden, dass ich das Interface als Vorlage für meinen eigenen Abstrakten Datentyp benutzen soll. :)

Gesagt getan:
Java:
import java.io.File;
import java.util.LinkedList;

public class FileTree{

	private final File file;
	private File parent;
	private final LinkedList<FileTree> childrens;
	
	public FileTree(File file){
		this.file = file;
		childrens = new LinkedList<FileTree>();
	}
	
	public FileTree(File file, File parent){
		this.file = file;
		this.parent = parent;
		childrens = new LinkedList<FileTree>();
	}
	
	public void addChildren(FileTree fileTree){
		childrens.add(fileTree);
	}
	
	public FileTree getChildrenAt(int i){
		return childrens.get(i);
	}
	
	public LinkedList<FileTree> getChildrens() {
		return this.childrens;
	}

	public File getData() {
		return this.file;
	}

	public File getParent() {
		return this.parent;
	}
	
	public int getChildCount(){
		return this.childrens.size();
	}
	
}

und

Java:
import java.io.File;

public class Main {
	
	public FileTree fileTree;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Main neu = new Main();
	}
	
	public Main() {
		// TODO Auto-generated constructor stub
		File dir = new File("C:\\TestDir");
		this.fileTree = new FileTree(dir);
		listFiles(this.fileTree);
		printTree(this.fileTree, 0);
	}
	
	public void listFiles(FileTree root){
		File[] files = root.getData().listFiles();
		for (int i = 0; i < files.length; i++) {
			FileTree node = new FileTree(files[i], root.getData());
			if(files[i].isDirectory() && files[i].canRead()){
				//System.out.println(files[i].getName());
				root.addChildren(node);
				listFiles(node);
			} else if(files[i].isFile() && files[i].canRead()){
				//System.out.println(files[i].getName());
				root.addChildren(node);				
			}
		}
	}
	
	public void printTree(FileTree tree, int a){
		for(int i = 1; i <= tree.getChildCount(); i++){
			for(int x = 0; x < a; x++){ System.out.print("  "); }
			System.out.print("|-");
			if(tree.getChildrenAt(i-1).getChildCount() < 1){
				System.out.println(i + "." + tree.getChildrenAt(i-1).getData().getName());
			} else {
				System.out.println(i + "." + tree.getChildrenAt(i-1).getData().getName());
				a++;
				printTree(tree.getChildrenAt(i-1), a);
				a--;;
			}
		}
	}

}

Testoutput (zur Überprüfung, ob die Daten richtig eingelesen und gespeichert wurden):
PHP:
|-1.Test.pdf
|-2.Test 1
  |-1.Test 1.1.txt
  |-2.Test 1.2.txt
  |-3.Test 1.3
    |-1.Test 1.3.1.txt
|-3.Test 2
  |-1.Test 2.1.txt

Es erscheint also das gewünschte Ergebnis! :) Vielen Dank noch mal! :)

Ich weiß allerdings nicht genau, ob die Implementierung des Vaterknotens soviel Sinn macht und auch richtig umgesetzt wurde.
 
Zuletzt bearbeitet von einem Moderator:

Neue Beiträge

Zurück