package javacodebook.io.dirtree; import java.io.*; public class FileTreeWalker { private File startDirectory; private FileVisitor visitor; private FilenameFilter filter; public FileTreeWalker(File startDirectory, FileVisitor visitor, FilenameFilter filter) throws IOException { if(!startDirectory.isDirectory()) throw new IOException("Kein Verzeichnis zum Start angegeben"); this.startDirectory = startDirectory; this.visitor = visitor; this.filter = filter; } public void start() throws IOException { start(startDirectory); } //Rekursiv durch alle Verzeichnisse laufen und alle Dateien an den //FileVisitor weitergeben, damit der seine Aktionen durchführen kann private void start(File startDir) throws IOException { File[] fileList = startDir.listFiles(); for(int i = 0; i < fileList.length; i++) { if(fileList[i].isDirectory()) { visitor.visitDirectory(fileList[i], FileVisitor.ENTER); start(fileList[i]); visitor.visitDirectory(fileList[i], FileVisitor.EXIT); } else { //Wenn ein Filter angegeben wurde, dann wird er //angewendet, sonst wird der Visitor direkt aufgerufen if(filter != null) { if(filter.accept(startDir, fileList[i].getName())) visitor.visitFile(fileList[i]); } else visitor.visitFile(fileList[i]); } } } } --- Neue Klasse --- package javacodebook.io.dirtree; import java.io.*; /** * Das Interface FileVisitor definiert die beiden Visit-Methoden, * mit denen Dateien und Verzeichnisse verarbeitet werden. */ public interface FileVisitor { //Konstanten für das Betreten bzw. Verlassen von Verzeichnissen public static final int ENTER = 1; public static final int EXIT = 2; /** Verarbeitet eine Datei */ public void visitFile(File f) throws IOException; /** Verarbeitet ein Verzeichnis */ public void visitDirectory(File f, int mode) throws IOException; } --- Neue Klasse --- package javacodebook.io.dirtree; import java.io.*; /** * Ein Beispiel für einen FileVisitor, der die Zeilen aller in einer * Verzeichnisstruktur befindlichen Dateien eines bestimmten Typs * zusammenzählt. */ public class CountLineNumbersVisitor implements FileVisitor { private int noOfLines = 0; public void visitFile(File f) throws IOException { //Der LineNumberReader zählt automatisch mit, in welcher Zeile er sich befindet LineNumberReader in = new LineNumberReader(new FileReader(f)); while(in.readLine() != null) ; //Die Gesamtzahl der Zeilen wird hochgezählt noOfLines += in.getLineNumber(); //Datei wieder schliessen in.close(); } public int getNoOfLines() { return noOfLines; } //Diese Methode wird für die Funktionalität nicht benötigt. public void visitDirectory(File f, int mode) throws IOException { } } --- Neue Klasse --- package javacodebook.io.dirtree; import java.io.*; /** * Ein einfacher FilenameFilter, der nur Dateien mit einer bestimmten Endung * akzeptiert. */ public class FileTypeFilter implements java.io.FilenameFilter { public static String FILETYPE_TXT = ".txt"; public static String FILETYPE_JAVA = ".java"; private String fileType; public FileTypeFilter(String fileType) { this.fileType = fileType; } public boolean accept(File dir, String name) { if(name.endsWith(fileType)) return true; return false; } } --- Neue Klasse --- package javacodebook.io.dirtree; import java.io.*; /** * * Die Startklasse, um die Benutzung des FileTreeWalkers mit einem FileVisitor * zu verdeutlichen. */ public class Starter { public static void main(String[] args) throws Exception { if(args.length < 1) usage(); String dir = args[0]; File startDir = new File(dir); CountLineNumbersVisitor visitor = new CountLineNumbersVisitor(); FileTreeWalker walker = new FileTreeWalker(startDir, visitor, new FileTypeFilter(FileTypeFilter.FILETYPE_JAVA)); walker.start(); int allLines = visitor.getNoOfLines(); System.out.println("Alle Dateien zusammen haben " + allLines + " Zeilen"); } public static void usage() { System.out.println("Benutzung: java javacodebook.io.dirtree.Starter Verzeichnis"); System.exit(0); } }