Verzeichnisse durchsuchen/bearbeiten/auslesen

Status
Nicht offen für weitere Antworten.

The_S

Top Contributor
Verzeichnisse durchsuchen/bearbeiten/auslesen

1. Ein Verzeichnis auslesen
2. Ein Verzeichnis durchsuchen
3. Ein Verzeichnis löschen
4. Ein Verzeichnis kopieren
5. Größe eines Verzeichnisses bestimmen
6. Allgemeine Klasse


1. Ein Verzeichnis auslesen

Um ein Verzeichnis auszulesen stellt das Java-API schon die Methode listFiles() bzw. list() in der Klasse java.io.File bereit:

Code:
File f = new File("C:/Programme");
File[] fileArray = f.listFiles();

Zurückgeliefert wird von listFiles() ein File-Array und von list() ein String-Array in welchem alle Dateien und Ordner in diesem Verzeichnis gespeichert werden. Damit lässt sich schon eine einfache Methode schreiben, mit welcher der Inhalt eines Verzeichnisses ausgegeben werden kann. Hilfreich ist noch die Methode File#isDirectory() mit welcher getestet wird ob das File auf einen Ordner verweist. Wichtig ist noch zu überprüfen ob das File-Array nichtgleich null ist, da z. B. bei nicht ausreichenden Berechtigungen um auf einen Ordnern zuzugreifen listFiles() null zurückliefert.

Code:
public void listDir(File dir) {

	File[] files = dir.listFiles();
	if (files != null) { // Erforderliche Berechtigungen etc. sind vorhanden
		for (int i = 0; i < files.length; i++) {
			System.out.print(files[i].getAbsolutePath());
			if (files[i].isDirectory()) {
				System.out.print(" (Ordner)\n");
			}
			else {
				System.out.print(" (Datei)\n");
			}
		}
	}
}

Leider gibt diese Methode nicht den Inhalt der evtl. vorhandenen Unterverzeichnisse aus. Dieses Problem lässt sich aber ganz einfach mit einer rekursiven Methode beheben.

Code:
public void listDir(File dir) {

	File[] files = dir.listFiles();
	if (files != null) {
		for (int i = 0; i < files.length; i++) {
			System.out.print(files[i].getAbsolutePath());
			if (files[i].isDirectory()) {
				System.out.print(" (Ordner)\n");
				listDir(files[i]); // ruft sich selbst mit dem 
					// Unterverzeichnis als Parameter auf
				}
			else {
				System.out.print(" (Datei)\n");
			}
		}
	}
}

2. Ein Verzeichnis durchsuchen

Prinzipiell ist es jetzt nicht mehr schwer aus der rekursiven Auflistung eine Suche zu basteln. Es muss nur noch ein Parameter mehr übergeben werden (nämlich der Dateiname nach welchem gesucht werden soll) und es wird ein Rückgabetyp benötigt in welchem die Treffer gespeichert werden.

Code:
public ArrayList<File> searchFile(File dir, String find) {

	File[] files = dir.listFiles();
	ArrayList<File> matches = new ArrayList<File> ();
	if (files != null) {
		for (int i = 0; i < files.length; i++) {
			if (files[i].getName().equalsIgnoreCase(find)) { // überprüft ob der Dateiname mit dem Suchstring
									 // übereinstimmt. Groß-/Kleinschreibung wird
									 // ignoriert.
				matches.add(files[i]);
			}
			if (files[i].isDirectory()) {
				matches.addAll(searchFile(files[i], find)); // fügt der ArrayList die ArrayList mit den
									    // Treffern aus dem Unterordner hinzu
			}
		}
	}
	return matches;
}

Da es mehrere Möglichkeiten gibt, wie man nach einer Datei suchen kann (String ist im Dateinamen enthalten, Datei fängt mit String an, Datei hört mit String auf, ...) beschränkt sich diese Methode auf die ßberprüfung, ob die Dateien (abgesehen von der Groß- und Kleinschreibung) exakt übereinstimmen und gilt somit eher als Vorlage für eine eigene Dateisuche.

Weitere Methoden gibt es hier

3. Ein Verzeichnis löschen

Mit der Methode File#delete() kann man eine Datei oder einen Ordner löschen. Zu beachten sind folgende Punkte:

1. Nur leere Verzeichnisse können gelöscht werden
2. Unter Umständen kann eine Datei nicht gelöscht werden (Schreibschutz, Datei wird gerade verwendet und ist deshalb gesperrt, ...). Sollte dies der Fall sein liefert delete() false zurück.

Code:
public void deleteDir(File dir) {

	File[] files = dir.listFiles();
	if (files != null) {
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				deleteDir(files[i]); // Verzeichnis leeren und anschließend löschen
			}
			else {
				files[i].delete(); // Datei löschen
			}
		}
		dir.delete(); // Ordner löschen
	}
}

4. Ein Verzeichnis kopieren

Auch hierfür muss die Methode natürlich nur geringfügig angepasst werden. Es wird nun das Quell- und Zielverzeichnis mitübergeben. Wie gewohnt werden alle Dateien und Ordner in einem File-Array gespeichert. Zusätzlich wird ein File-Objekt benötigt welches den neuen Zielpfad anhand des Quellpfades für jede Datei/jeden Ordner bestimmt. Mittels File#mkdirs() wird das Zielverzeichnis inkl. allen benötigten ßberordnern (sofern noch nicht vorhanden) neu angelegt.

Code:
public void copyDir(File quelle, File ziel) throws FileNotFoundException, IOException {
		
	File[] files = quelle.listFiles();
	File newFile = null; // in diesem Objekt wird für jedes File der Zielpfad gespeichert.
			     // 1. Der alte Zielpfad
			     // 2. Das systemspezifische Pfadtrennungszeichen
			     // 3. Der Name des aktuellen Ordners/der aktuellen Datei
	ziel.mkdirs();	     // erstellt alle benötigten Ordner
	if (files != null) {
		for (int i = 0; i < files.length; i++) {
				newFile = new File(ziel.getAbsolutePath() + System.getProperty("file.separator") + files[i].getName());
			if (files[i].isDirectory()) {
				copyDir(files[i], newFile);
			}
			else {
				copyFile(files[i], newFile);
			}
		}
	}
}

Die Methode copyFile(File quelle, File ziel) welche das eigentliche Kopieren mithilfe eines BufferedInputStreams und eines BufferedOutputStreams übernimmt schaut wie folgt aus:

Code:
public void copyFile(File file, File ziel) throws FileNotFoundException, IOException {
		
	BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
	BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(ziel, true));
	int bytes = 0;
	while ((bytes = in.read()) != -1) { // Datei einlesen
		out.write(bytes); // Datei schreiben
	}
	in.close();
	out.close();
}

5. Größe eines Verzeichnisses bestimmen

Auch hier muss die Sache wieder rekursiv angegangen werden. Mit File#length() bekommt man die Größe der Datei in byte als long zurückgeliefert.

Code:
public long getDirSize(File dir) {
		
	long size = 0;
	File[] files = dir.listFiles();
	if (files != null) {
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				size += getDirSize(files[i]); // Gesamtgröße des Verzeichnisses aufaddieren
			}
			else {
				size += files[i].length(); // Größe der Datei aufaddieren
			}
		}
	}
	return size;
}

6. Allgemeine Klasse

Hier noch mal alle Methoden in einer Klasse "vereint":

Code:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public class DirEdit {

	public void copyDir(File quelle, File ziel) throws FileNotFoundException, IOException {
		
		File[] files = quelle.listFiles();
		File newFile = null;
		ziel.mkdirs();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				newFile = new File(ziel.getAbsolutePath() + System.getProperty("file.separator") + files[i].getName());
				if (files[i].isDirectory()) {
					copyDir(files[i], newFile);
				}
				else {
					copyFile(files[i], newFile);
				}
			}
		}
	}
	
	public void copyFile(File file, File ziel) throws FileNotFoundException, IOException {
		
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(ziel, true));
		int bytes = 0;
		while ((bytes = in.read()) != -1) {
			out.write(bytes);
		}
		in.close();
		out.close();
	}

	public void deleteDir(File dir) {

		File[] files = dir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					deleteDir(files[i]);
				}
				else {
					files[i].delete();
				}
			}
			dir.delete();
		}
	}
	
	public ArrayList<File> searchFile(File dir, String find) {

		File[] files = dir.listFiles();
		ArrayList<File> matches = new ArrayList<File> ();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].getName().equalsIgnoreCase(find)) { 
					matches.add(files[i]);
				}
				if (files[i].isDirectory()) {
					matches.addAll(searchFile(files[i], find)); 
				}
			}
		}
		return matches;
	}
	
	public void listDir(File dir) {

		File[] files = dir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				System.out.print(files[i].getAbsolutePath());
				if (files[i].isDirectory()) {
					System.out.print(" (Ordner)\n");
					listDir(files[i]); 
				}
				else {
					System.out.print(" (Datei)\n");
				}
			}
		}
	}
	
	public long getDirSize(File dir) {
		
		long size = 0;
		File[] files = dir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					size += getDirSize(files[i]);
				}
				else {
					size += files[i].length();
				}
			}
		}
		return size;
	}
}
 

Guybrush Threepwood

Top Contributor
Hi,
Java7 bietet zahlreiche neue Möglichkeiten, z. B.:

1. Neue Files-Hilsklasse, die es beispielsweise ermöglicht, Zeilen einer Datei auslesen
Java:
    List<String> lines =  Files.readAllLines(  
    FileSystems.getDefault().getPath("test.txt"), StandardCharsets.UTF_8);  
      
    for (String line : lines) System.out.println(line);

Quelle:
7 new cool features in Java 7 @ sellmic.com
Files (Java Platform SE 7 )



2. ZIP-Dateien transparent als Datei-System verwenden

Java:
Path zipfile = Paths.get("/codeSamples/zipfs/zipfstest.zip");
FileSystem fs = FileSystems.newFileSystem(zipfile, env, null);

Quelle: Zip File System Provider

3. Verzeichnisse rekursive durchwandern
Quelle: Rekursive Ablufe des Verzeichnisbaums (FileVisitor) unter Java 7 mit NIO.2


4. Änderungen am Dateisystem registrieren

Quelle: Watching a Directory for Changes (The Java™ Tutorials > Essential Classes > Basic I/O)


5. .... etc.
Viele Grüße,
Guybrush
 
Zuletzt bearbeitet von einem Moderator:
Status
Nicht offen für weitere Antworten.

Oben