Verzeichnisse durchsuchen/bearbeiten/auslesen (Java): Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
 
(9 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
 
=Ein Verzeichnis auslesen=
 
=Ein Verzeichnis auslesen=
 
Um ein Verzeichnis auszulesen stellt das Java-API schon die Methode listFiles() bzw. list() in der Klasse java.io.File bereit:
 
Um ein Verzeichnis auszulesen stellt das Java-API schon die Methode listFiles() bzw. list() in der Klasse java.io.File bereit:
<code=java>
+
<syntaxhighlight lang="java">
 
File f = new File("C:/Programme");
 
File f = new File("C:/Programme");
 
File[] fileArray = f.listFiles();
 
File[] fileArray = f.listFiles();
</code=java>
+
</syntaxhighlight>
  
 
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.
 
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=java>
+
<syntaxhighlight lang="java">
 
public void listDir(File dir) {
 
public void listDir(File dir) {
  
Zeile 23: Zeile 23:
 
}
 
}
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
 
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.
 
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=java>
+
<syntaxhighlight lang="java">
 
public void listDir(File dir) {
 
public void listDir(File dir) {
  
Zeile 44: Zeile 44:
 
}
 
}
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
 
==Eine Datei auslesen==
 
==Eine Datei auslesen==
 
In Java 7 kamen neue Hilfsklassen hinzu, die ein einfacheres Auslesen von Dateien ermöglichen:
 
In Java 7 kamen neue Hilfsklassen hinzu, die ein einfacheres Auslesen von Dateien ermöglichen:
<code=java>
+
<syntaxhighlight lang="java">
    List<String> lines =  Files.readAllLines(FileSystems.getDefault().getPath("Text.txt"), StandardCharsets.UTF_8);           
+
List<String> lines =  Files.readAllLines(FileSystems.getDefault().getPath("Text.txt"), StandardCharsets.UTF_8);           
        for (String line : lines) {
+
for (String line : lines) {
            System.out.println(line);
+
    System.out.println(line);
        }
+
}
</code=java>
+
</syntaxhighlight>
 +
 
 +
==Eine ZIP-Datei transparent innerhalb des Dateisystems verwenden==
 +
Inhalte von gepackten Archiven lassen sich auch seit Java 7 direkt im Dateisystem darstellen.
 +
<syntaxhighlight lang="java">
 +
Path zipfile = Paths.get("/beispiele/zipfs/archiv.zip");
 +
FileSystem fs = FileSystems.newFileSystem(zipfile, env, null);
 +
</syntaxhighlight>
  
 
=Ein Verzeichnis durchsuchen=
 
=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.
 
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=java>
+
<syntaxhighlight lang="java">
 
public ArrayList<File> searchFile(File dir, String find) {
 
public ArrayList<File> searchFile(File dir, String find) {
  
Zeile 77: Zeile 84:
 
return matches;
 
return matches;
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
 
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.
 
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.
Zeile 86: Zeile 93:
 
# Nur leere Verzeichnisse können gelöscht werden
 
# Nur leere Verzeichnisse können gelöscht werden
 
# 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.
 
# 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=java>
+
<syntaxhighlight lang="java">
 
public void deleteDir(File dir) {
 
public void deleteDir(File dir) {
  
Zeile 102: Zeile 109:
 
}
 
}
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
 
=Ein Verzeichnis kopieren=
 
=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 <code>File#mkdirs()</code> wird das Zielverzeichnis inkl. allen benötigten ßberordnern (sofern noch nicht vorhanden) neu angelegt.
 
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 <code>File#mkdirs()</code> wird das Zielverzeichnis inkl. allen benötigten ßberordnern (sofern noch nicht vorhanden) neu angelegt.
<code=java>
+
<syntaxhighlight lang="java">
 
public void copyDir(File quelle, File ziel) throws FileNotFoundException, IOException {
 
public void copyDir(File quelle, File ziel) throws FileNotFoundException, IOException {
 
 
Zeile 127: Zeile 134:
 
}
 
}
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
 
Die Methode copyFile(File quelle, File ziel) welche das eigentliche Kopieren mithilfe eines BufferedInputStreams und eines BufferedOutputStreams übernimmt schaut wie folgt aus:
 
Die Methode copyFile(File quelle, File ziel) welche das eigentliche Kopieren mithilfe eines BufferedInputStreams und eines BufferedOutputStreams übernimmt schaut wie folgt aus:
<code=java>
+
<syntaxhighlight lang="java">
 
public void copyFile(File file, File ziel) throws FileNotFoundException, IOException {
 
public void copyFile(File file, File ziel) throws FileNotFoundException, IOException {
 
 
Zeile 142: Zeile 149:
 
out.close();
 
out.close();
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
  
 
=Größe eines Verzeichnisses bestimmen=
 
=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.
 
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=java>
+
<syntaxhighlight lang="java">
  
  
Zeile 166: Zeile 173:
 
return size;
 
return size;
 
}
 
}
</code=java>
+
</syntaxhighlight>
 +
 
 +
=Ein Verzeichnis auf Veränderungen überwachen=
 +
[http://docs.oracle.com/javase/tutorial/essential/io/notification.html Oracle - Watching a Directory for Changes]
  
 
=Allgemeine Klasse (komplettes Beispiel)=
 
=Allgemeine Klasse (komplettes Beispiel)=
 
Hier noch mal alle Methoden in einer Klasse "vereint":
 
Hier noch mal alle Methoden in einer Klasse "vereint":
<code=java>
+
<syntaxhighlight lang="java">
 
import java.io.BufferedInputStream;
 
import java.io.BufferedInputStream;
 
import java.io.BufferedOutputStream;
 
import java.io.BufferedOutputStream;
Zeile 279: Zeile 289:
 
}
 
}
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
=ZIP-Dateien transparent innerhalb des Datei-Systems verwenden=  
+
{{Fragen stellen}}
Inhalte von gepackten Archiven lassen sich auch seit Java 7 direkt im Dateisystem darstellen.
+
 
<code=java>
+
=Quellen und weiterführende Links=
Path zipfile = Paths.get("/beispiele/zipfs/archiv.zip");
+
*[http://docs.oracle.com/javase/tutorial/essential/io/index.html Oracle - Essential Classes - Basic I/O]
FileSystem fs = FileSystems.newFileSystem(zipfile, env, null);
+
*[[DirectoryChooser]]
</code=java>
 
  
 
[[Kategorie:Java]]
 
[[Kategorie:Java]]

Aktuelle Version vom 27. Januar 2020, 17:42 Uhr

Ein Verzeichnis auslesen

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

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.

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.

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

Eine Datei auslesen

In Java 7 kamen neue Hilfsklassen hinzu, die ein einfacheres Auslesen von Dateien ermöglichen:

List<String> lines =  Files.readAllLines(FileSystems.getDefault().getPath("Text.txt"), StandardCharsets.UTF_8);          
for (String line : lines) {
     System.out.println(line);
}

Eine ZIP-Datei transparent innerhalb des Dateisystems verwenden

Inhalte von gepackten Archiven lassen sich auch seit Java 7 direkt im Dateisystem darstellen.

Path zipfile = Paths.get("/beispiele/zipfs/archiv.zip");
FileSystem fs = FileSystems.newFileSystem(zipfile, env, null);

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.

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.

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.
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
	}
}

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.

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:

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


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.

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

Ein Verzeichnis auf Veränderungen überwachen

Oracle - Watching a Directory for Changes

Allgemeine Klasse (komplettes Beispiel)

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

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


Fragen

Das Thema wurde nicht ausreichend behandelt? Du hast Fragen dazu und brauchst weitere Informationen? Lass Dir von uns helfen!

Wir helfen dir gerne!


Dir hat dieser Artikel gefallen? Oder Du hast Fehler entdeckt und möchtest zur Berichtigung beitragen? Prima! Schreibe einen Kommentar!

Du musst angemeldet sein, um einen Kommentar abzugeben.


Quellen und weiterführende Links

--The_S (08.08.2006, 21:07 Uhr)