Mittwoch, 21. Januar 2009

 

Verzeichnisse mit Java durchsuchen

Die File-Klasse (java.io.File) dient nicht nur dazu, einzelne Dateien zu behandeln, man kann ein Objekt vom Typ File auch für Verzeichnisse verwenden. Die Methode listFiles() ist dafür geeignet. Folgende Beispielklasse liefert eine Liste von Dateien, auf die ein bestimmtes Muster passt. Dazu wird ein regulärer Ausdruck verwendet (java.util.regex.Pattern). Die Klasse durchsucht nicht rekursiv auch alle Unterverzeichnisse und verwendet dazu einen Stack (java.util.Stack). Die Schreibweise List<File> beschränkt die Liste auf den (Objekt-)Typ File:

/**
* java-directories/utils.dir.FileFinder.java
* @author (c) 2009, Harald R. Haberstroh
* 21.01.2009
*/
package utils.dir;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.regex.Pattern;

/**
* Suchen aller Dateien in einem Verzeichnis bzw. Unterverzeichnissen nach einem
* bestimmten Muster (entnommen aus "Java ist eine Insel").
*
* Ergänzt um Logging, da NullPointerException bei Verzeichnis mit seeeeehr
* vielen Dateien und Unterverzeichnissen.
* Tatsächliche Fehlerursache waren symbolische Links auf Verzeichnisse, auf
* die ich keine Leserechte besaß.
*
* @author Harald R. Haberstroh (hh)
*
*/
public class FileFinder {
private static Logger logger = Logger.getAnonymousLogger();
/**
* initialisiere Klasse, setze Logging aus
*/
static {
logger.setLevel(Level.OFF); // default kein Logging
}

/**
* Setze Logging Level
*
* @param level
*/
public static void setLogLevel(Level level) {
logger.setLevel(level);
}

/**
* Logging zusätzlich in Datei (*.txt Text, XML sonst)
*
* @param filename
* Logfilename
*/
public static void setLogFile(String filename) {
try {
if (filename.endsWith("txt")) { // lesbarer Text in Datei
Handler handler = new FileHandler(filename);
handler.setFormatter(new SimpleFormatter());
logger.addHandler(handler);
} else { // sonst XML (default)
logger.addHandler(new FileHandler(filename));
}
} catch (IOException e) {
e.printStackTrace(); // kann Logfile nicht schreiben, seeeehr schlimm
}
}

/**
* suche alle Dateien mit gegebenem Muster.
*
* @param start
* Startverzeichnis
* @param extensionPattern
* Dateimuster (regulärer Ausdruck)
* @return Liste von Dateien
*/
public static List find(String start, String extensionPattern) {
List files = new ArrayList(1024);
Stack dirs = new Stack();
File startdir = new File(start);
Pattern p = Pattern.compile(extensionPattern, Pattern.CASE_INSENSITIVE);

if (startdir.isDirectory()) {
logger.info(startdir + " ist ein Verzeichnis");
dirs.push(startdir); // Startverzeichnis auf den Stack
}

while (dirs.size() > 0) { // solange ein Verzeichnis am Stack
try {
File[] listFiles = dirs.pop().listFiles();
logger.info("prüfe " + listFiles.length + " Dateien");
for (File file : listFiles) { // alle Dateien des Verzeichnisses
if (file.isDirectory()) {
logger.info(file + " ist ein Verzeichnis");
dirs.push(file);
} else {
logger.info(file + " ist eine Datei");
if (p.matcher(file.getName()).matches()) {
files.add(file); // passt das Muster, dann in die Liste
}
}
}
} catch (Exception e) {
logger.severe(e.getLocalizedMessage());
e.printStackTrace();
System.exit(1);
}
}
return files;
}
}

Die Klasse verwendet Logging, welches aber standardmäßig abgeschaltet ist. Beachten Sie das Codestück

static {
logger.setLevel(Level.OFF); // default kein Logging
}

welches beim Laden der Klasse ausgeführt wird (fast immer beim Starten des Programmes). Diese Anweisungen sind nicht an ein bestimmtes Objekt gebunden.

Verwenden kann man die Klasse z.B. zum Ermitteln aller Bilddateien in gegebenen Verzeichnissen:

/**
* listet alle Bilddateien der gegebenen Verzeichnisse.
*
* @param args
* Verzeichnisse, aktuelles Verzeichns, falls leer
*/
public static void main(String[] args) {
// Logging aktivieren durch entfernen der Kommentarzeichen:
// FileFinder.setLogFile("filefinder.txt");
// FileFinder.setLogLevel(Level.ALL);
String[] dirs = null;
if (args.length > 0) {
dirs = args;
} else {
dirs = new String[1];
dirs[0] = new File(System.getProperty("user.dir")).getAbsolutePath();
}
for (String dir : dirs) {
List files = FileFinder.find(dir,
"(.*\\.gif$)|(.*\\.png$)|(.*\\.jpg$)"); // *.gif, *.png, *.jpg
System.out.printf("Verzeichns %s - %s Datei%s:\n", dir,
files.size() == 0 ? "keine" : "" + files.size(),
files.size() == 1 ? "" : "en");
for (File file : files) {
System.out.println(" " + file.getAbsolutePath());
}

}
}

Labels: ,


Kommentare:

Kommentar veröffentlichen

Abonnieren Kommentare zum Post [Atom]





<< Startseite

This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]