Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Exceptions
7 Äußere.innere Klassen
8 Besondere Klassen der Java SE
9 Generics<T>
10 Architektur, Design und angewandte Objektorientierung
11 Die Klassenbibliothek
12 Einführung in die nebenläufige Programmierung
13 Einführung in Datenstrukturen und Algorithmen
14 Einführung in grafische Oberflächen
15 Einführung in Dateien und Datenströme
16 Einführung in die <XML>-Verarbeitung mit Java
17 Einführung ins Datenbankmanagement mit JDBC
18 Bits und Bytes und Mathematisches
19 Die Werkzeuge des JDK
A Die Klassenbibliothek
Stichwort

Download:
- Aufgaben, ca. 1,1 MB
- Programme, ca. 12,8 MB

Buch bestellen
Ihre Meinung?

Spacer
Java ist auch eine Insel von Christian Ullenboom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
Galileo Computing
1308 S., 10., aktualisierte Auflage, geb., mit DVD
ca. 49,90 Euro, ISBN 978-3-8362-1802-3
Pfeil 15 Einführung in Dateien und Datenströme
Pfeil 15.1 Datei und Verzeichnis
Pfeil 15.1.1 Dateien und Verzeichnisse mit der Klasse File
Pfeil 15.1.2 Verzeichnis oder Datei? Existiert es?
Pfeil 15.1.3 Verzeichnis- und Dateieigenschaften/-attribute
Pfeil 15.1.4 Umbenennen und Verzeichnisse anlegen
Pfeil 15.1.5 Verzeichnisse auflisten und Dateien filtern
Pfeil 15.1.6 Dateien und Verzeichnisse löschen
Pfeil 15.2 Dateien mit wahlfreiem Zugriff
Pfeil 15.2.1 Ein RandomAccessFile zum Lesen und Schreiben öffnen
Pfeil 15.2.2 Aus dem RandomAccessFile lesen
Pfeil 15.2.3 Schreiben mit RandomAccessFile
Pfeil 15.2.4 Die Länge des RandomAccessFile
Pfeil 15.2.5 Hin und her in der Datei
Pfeil 15.3 Dateisysteme unter NIO.2
Pfeil 15.3.1 FileSystem und Path
Pfeil 15.3.2 Die Utility-Klasse Files
Pfeil 15.4 Stream-Klassen und Reader/Writer am Beispiel von Dateien
Pfeil 15.4.1 Mit dem FileWriter Texte in Dateien schreiben
Pfeil 15.4.2 Zeichen mit der Klasse FileReader lesen
Pfeil 15.4.3 Kopieren mit FileOutputStream und FileInputStream
Pfeil 15.4.4 Datenströme über Files mit NIO.2 beziehen
Pfeil 15.5 Basisklassen für die Ein-/Ausgabe
Pfeil 15.5.1 Die abstrakten Basisklassen
Pfeil 15.5.2 Übersicht über Ein-/Ausgabeklassen
Pfeil 15.5.3 Die abstrakte Basisklasse OutputStream
Pfeil 15.5.4 Die Schnittstellen Closeable, AutoCloseable und Flushable
Pfeil 15.5.5 Die abstrakte Basisklasse InputStream
Pfeil 15.5.6 Ressourcen aus dem Klassenpfad und aus Jar?Archiven laden
Pfeil 15.5.7 Die abstrakte Basisklasse Writer
Pfeil 15.5.8 Die abstrakte Basisklasse Reader
Pfeil 15.6 Datenströme filtern und verketten
Pfeil 15.6.1 Streams als Filter verketten (verschachteln)
Pfeil 15.6.2 Gepufferte Ausgaben mit BufferedWriter und BufferedOutputStream
Pfeil 15.6.3 Gepufferte Eingaben mit BufferedReader/BufferedInputStream
Pfeil 15.7 Vermittler zwischen Byte-Streams und Unicode-Strömen
Pfeil 15.7.1 Datenkonvertierung durch den OutputStreamWriter
Pfeil 15.7.2 Automatische Konvertierungen mit dem InputStreamReader

15 Einführung in Dateien und DatenströmeZur nächsten Überschrift

»Schlagfertigkeit ist jede Antwort, die so klug ist, dass der Zuhörer wünscht, er hätte sie gegeben.«
– Elbert Green Hubbard (1856–1915)

Computer sind für uns so nützlich, weil sie Daten bearbeiten. Der Bearbeitungszyklus beginnt mit dem Einlesen der Daten, umfasst das Verarbeiten und endet mit der Ausgabe der Daten. In der deutschsprachigen Informatikliteratur wird deswegen auch vom EVA-Prinzip der Datenverarbeitungsanlagen gesprochen. In frühen EDV-Zeiten wurde die Eingabe vom Systemoperator auf Lochkarten gestanzt. Glücklicherweise sind diese Zeiten vorbei. Heutzutage speichern wir unsere Daten in Dateien (engl. files[205](Das englische Wort »file« geht auf das lateinische Wort »filum« zurück. Dies bezeichnete früher eine auf Draht aufgereihte Sammlung von Schriftstücken.)) und Datenbanken ab. Es ist wichtig, anzumerken, dass eine Datei nur in ihrem Kontext interessant ist, andernfalls beinhaltet sie für uns keine Information – die Sichtweise auf eine Datei ist demnach wichtig. Auch ein Programm besteht aus Daten und wird oft in Form einer Datei repräsentiert.

Das java.io-Paket bietet zahlreiche dateiorientierte Operationen. Dazu zählen Möglichkeiten, Dateien anzulegen, zu löschen, umzubenennen und sie in Verzeichnissen zu strukturieren. Diese gehören schon seit Java 1.0 zur API, und wir wollen uns zuerst damit beschäftigen. Java 7 krempelt diese API um und macht insbesondere die zentrale File-Klasse überflüssig. Die neue API liegt getrennt in einem neuen Paket namens java.nio.file und wird in dem Buch intensiv nach der traditionellen API vorgestellt.


Rheinwerk Computing - Zum Seitenanfang

15.1 Datei und VerzeichnisZur nächsten ÜberschriftZur vorigen Überschrift

Die Klasse File hat die Aufgabe, Dateioperationen plattformunabhängig durchzuführen. Plattformunabhängigkeit ist aber auch eine Einschränkung, denn wie sollen Rechte vergeben werden, wenn dies etwa der Macintosh mit Mac OS X oder ein Android Smartphone nicht unterstützt? Unix und Windows haben zwei völlig verschiedene Ansätze zur Rechteverwaltung. Die File-Klasse ignoriert diese Frage und bietet überhaupt keine Lösung. In NIO.2 jedoch geht Java einen anderen Weg und neigt wieder deutlich mehr zu plattformspezifischen Details.


Rheinwerk Computing - Zum Seitenanfang

15.1.1 Dateien und Verzeichnisse mit der Klasse FileZur nächsten ÜberschriftZur vorigen Überschrift

Ein File-Objekt repräsentiert einen Datei- oder Verzeichnisnamen im Dateisystem. Die Datei oder das Verzeichnis, das das File-Objekt beschreibt, muss nicht physikalisch existieren. Der Verweis wird durch einen Pfadnamen spezifiziert. Dieser kann absolut oder relativ zum aktuellen Verzeichnis angegeben werden.

Beispiel

Erzeuge ein File-Objekt für das Laufwerk C:/:

File f = new File( "C:/" );
System.out.println( f ); // C:\

Folgende Konstruktoren erzeugen ein File-Objekt:

class java.io.File
implements Serializable, Comparable<File>
  • File(String pathname)
    Erzeugt ein File-Objekt aus einem Dateinamen.
  • File( String parent, String child)
  • File(File parent, String child)
    Setzt ein neues File-Objekt aus einem Basisverzeichnis und einem weiteren Teil zusammen, der auch wieder ein Verzeichnis oder ein Dateiname sein kann.
  • File(URI uri)
    Erfragt von uri den Pfadnamen (uri.getPath()) und erzeugt ein neues File-Objekt. Ist uri gleich null, folgt eine NullPointerException. Ist die URI falsch formuliert, gibt es eine IllegalArgumentException.

Die Pfadangabe kann in allen Fällen absolut sein, muss es aber nicht.

Pfadtrenner

Die Angabe des Pfades ist wegen der Pfadtrenner plattformabhängig. Auf Windows-Rechnern trennt ein Backslash »\« die Pfade, auf Unix-Maschinen ein normaler Slash »/« und unter dem älteren MAC OS 9 ein Doppelpunkt.

Glücklicherweise speichert die Klasse File den Pfadtrenner in zwei öffentlichen Konstanten: File.separatorChar[206](Eigentlich sollte der Variablenname großgeschrieben werden, da die Variable als public static final char eine Konstante ist.) ist ein char, und File.separator stellt den Pfadtrenner als String bereit (dies ist wiederum auf System.getProperty("file.separator") zurückzuführen).

Hinweis

Wie bei den Dateitrennern gibt es einen Unterschied bei der Darstellung des Wurzelverzeichnisses. Unter Unix ist dies ein einzelnes Divis »/«, und unter Windows steht die Laufwerksbezeichnung vor dem Doppelpunkt und dem Backslash-Zeichen (»Z:\«).

Namen erfragen und auflösen

Mit einem File-Objekt erfragen ganz unterschiedliche Methoden den Dateinamen, den kompletten Pfad, das vorangehende Verzeichnis und ob eine Angabe absolut oder relativ ist. Bei einigen Methoden lässt sich wählen, ob die Rückgabe ein String-Objekt mit dem Dateinamen sein soll oder ein File-Objekt.

Beispiel

Liefere einen Dateinamen, bei dem die relativen Bezüge aufgelöst sind:

try
{
File f = new File("C:/./WasNDas//..\\Programme/")
.getCanonicalFile();
System.out.println( f ); // C:\Programme
}
catch ( IOException e ) { e.printStackTrace(); }
Nicht viele Methoden der File-Klasse lösen eine IOException aus, diese ist eher eine Ausnahme.

Abbildung

Abbildung 15.1: Klassendiagramm für File

class java.io.File
implements Serializable, Comparable<File>
  • String getName()
    Gibt den Dateinamen zurück.
  • String getPath()
    Gibt den Pfadnamen zurück.
  • String getAbsolutePath()
  • File getAbsoluteFile()
    Liefert den absoluten Pfad. Ist das Objekt kein absoluter Pfadname, so wird ein Objekt aus dem aktuellen Verzeichnis, einem Separator-Zeichen und dem Dateinamen aufgebaut.
  • String getCanonicalPath () throws IOException
  • File getCanonicalFile() throws IOException
    Gibt den Pfadnamen des Dateiobjekts zurück, der keine relativen Pfadangaben mehr enthält. Kann im Gegensatz zu den anderen Pfadmethoden eine IOException aufrufen, da mitunter verbotene Dateizugriffe erfolgen.
  • String getParent(), File getParentFile()
    Gibt den Pfad des Vorgängers als String- oder File-Objekt zurück. Die Rückgabe ist null, wenn es keinen Vater gibt, etwa beim Wurzelverzeichnis.
  • boolean isAbsolute()
    Liefert true, wenn der Pfad in der systemabhängigen Notation absolut ist.

Rheinwerk Computing - Zum Seitenanfang

15.1.2 Verzeichnis oder Datei? Existiert es?Zur nächsten ÜberschriftZur vorigen Überschrift

Das File-Objekt muss nicht unbedingt eine existierende Datei oder ein existierendes Verzeichnis repräsentieren. Für Dateioperationen mit File-Objekten und nachfolgendem Zugriff testet exists(), ob die Datei oder das Verzeichnis tatsächlich vorhanden ist. Da nun aber ein File-Objekt Dateien sowie Verzeichnisse gleichzeitig repräsentiert, ermöglichen isDirectory() und isFile() eine genauere Aussage über den File-Typ. Es kann gut sein, dass für eine File weder isDirectory() noch isFile() die Rückgabe true liefert (in Java können nur normale Dateien erzeugt werden).

class java.io.File
implements Serializable, Comparable<File>
  • boolean exists()
    Liefert true, wenn das File-Objekt eine existierende Datei oder einen existierenden Ordner repräsentiert.
  • boolean isDirectory()
    Gibt true zurück, wenn es sich um ein Verzeichnis handelt.
  • boolean isFile()
    Liefert true, wenn es sich um eine »normale« Datei handelt (kein Verzeichnis und keine Datei, die vom zugrunde liegenden Betriebssystem als besonders markiert wird, keine Blockdateien, Verknüpfungen).

Rheinwerk Computing - Zum Seitenanfang

15.1.3 Verzeichnis- und Dateieigenschaften/-attributeZur nächsten ÜberschriftZur vorigen Überschrift

Eine Datei oder ein Verzeichnis besitzt zahlreiche Eigenschaften, die sich mit Anfragemethoden auslesen lassen. In einigen wenigen Fällen lassen sich die Attribute auch ändern.

class java.io.File
implements Serializable, Comparable<File>
  • boolean canExecute()
  • boolean canRead()
  • boolean canWrite()
  • Liefert true, wenn die Ausführungsrechte/Leserechte/Schreibrechte gesetzt sind.
  • long length()
    Gibt die Länge der Datei in Byte zurück oder 0L, wenn die Datei nicht existiert oder es sich um ein Verzeichnis handelt.

Änderungsdatum einer Datei

Eine Datei verfügt unter jedem Dateisystem nicht nur über Attribute wie Größe und Rechte, sondern verwaltet auch das Datum der letzten Änderung. Letzteres nennt sich Zeitstempel. Die File-Klasse verfügt zum Abfragen dieser Zeit über die Methode lastModified() und zum Setzen über setLastModified().

Die Methode setLastModified() ändert (wenn möglich) den Zeitstempel, und ein anschließender Aufruf von lastModified() liefert die gesetzte Zeit (womöglich gerundet) zurück. Die Methode ist von vielfachem Nutzen, aber in Hinblick auf die Sicherheit bedenklich, denn ein Programm kann den Dateiinhalt einschließlich des Zeitstempels ändern. Auf den ersten Blick ist nicht mehr erkennbar, dass eine Veränderung der Datei vorgenommen wurde. Doch die Methode ist von größerem Nutzen bei der Programmerstellung, wo Quellcodedateien etwa mit Objektdateien verbunden sind. Nur über einen Zeitstempel ist eine einigermaßen intelligente Projektdateiverwaltung möglich.

Dabei bleibt es verwunderlich, warum lastModified() nicht als veraltet ausgezeichnet ist und zu getLastModified() wurde, wo doch nun die passende Methode zum Setzen der Namensgebung genügt.

class java.io.File
implements Serializable, Comparable<File>
  • long lastModified()
    Liefert den Zeitpunkt, zu dem die Datei zum letzten Mal geändert wurde. Die Zeit wird in Millisekunden ab dem 1. Januar 1970, 00:00:00 UTC, gemessen. Die Methode liefert 0, wenn die Datei nicht existiert oder ein Ein-/Ausgabefehler auftritt.
  • boolean setLastModified(long time)
    Setzt die Zeit (wann die Datei zuletzt geändert wurde). Die Zeit ist wiederum in Millisekunden seit dem 1. Januar 1970 angegeben. Ist das Argument negativ, dann wird eine IllegalArgumentException ausgelöst.
Hinweis

Zwar lässt Java die Ermittlung der Zeit der letzten Änderung zu, doch gilt dies nicht für die Erzeugungszeit. Das Standard-Dateisystem von Unix-Systemen speichert diese Zeit nicht. Windows speichert sie hingegen schon, sodass hier grundsätzlich der Zugriff, etwa über JNI, möglich wäre. Legt ein Java-Programm die Dateien an, deren Anlegezeiten später wichtig sind, müssen die Zeiten beim Anlegen gemessen und gespeichert werden. Falls die Datei nicht verändert wird, stimmt lastModified() mit der Anlegezeit überein.


Rheinwerk Computing - Zum Seitenanfang

15.1.4 Umbenennen und Verzeichnisse anlegenZur nächsten ÜberschriftZur vorigen Überschrift

Mit mkdir() lassen sich Verzeichnisse anlegen und mit renameTo() Dateien oder Verzeichnisse umbenennen.

class java.io.File
implements Serializable, Comparable<File>
  • boolean mkdir()
    Legt das Unterverzeichnis an.
  • boolean mkdirs()
    Legt das Unterverzeichnis inklusive weiterer Verzeichnisse an.
  • boolean renameTo(File d)
    Benennt die Datei in den Namen um, der durch das File-Objekt d gegeben ist. Ging alles gut, wird true zurückgegeben. Bei zwei Dateinamen alt und neu benennt new File(alt).renameTo(new File(neu)); die Datei um. Die Methode muss vom Betriebssystem nicht atomar ausgeführt werden, und die tatsächliche Implementierung ist von der JVM und vom Betriebssystem abhängig.

Über renameTo() sollte noch ein Wort verloren werden: File-Objekte sind immutable, stehen also immer nur für genau eine Datei. Ändert sich der Dateiname, ist das File-Objekt ungültig, und es ist kein Zugriff mehr über dieses File-Objekt erlaubt. Auch wenn eine Laufzeitumgebung keine Exception auslöst, sind alle folgenden Ergebnisse von Anfragen unsinnig.


Rheinwerk Computing - Zum Seitenanfang

15.1.5 Verzeichnisse auflisten und Dateien filternZur nächsten ÜberschriftZur vorigen Überschrift

Um eine Verzeichnisanzeige oder einen Dateiauswahldialog zu programmieren, benötigen wir eine Liste von Dateien, die in einem Verzeichnis liegen. Ein Verzeichnis kann reine Dateien oder auch wieder Unterverzeichnisse besitzen. Die list()- und listFiles()-Methoden der Klasse File geben ein Feld von Zeichenketten mit Dateien und Verzeichnissen beziehungsweise ein Feld von File-Objekten mit den enthaltenen Elementen zurück.

class java.io.File
implements Serializable, Comparable<File>
  • File[] listFiles()
  • String[] list()
    Gibt eine Liste der Dateien in einem Verzeichnis als File-Array oder String-Array zurück. Das Feld enthält weder ».« noch »..«.
Beispiel

Ein einfacher Directory-Befehl ist leicht mittels einiger Zeilen programmiert:

String[] entries = new File( "." ).list();
System.out.println( Arrays.toString(entries) );

Die einfache Methode list() liefert dabei nur relative Pfade, also einfach den Dateinamen oder den Verzeichnisnamen. Den absoluten Namen zu einer Dateiquelle müssen wir also erst zusammensetzen. Praktischer ist da schon die Methode listFiles(), da wir hier komplette File-Objekte bekommen, die ihre ganze Pfadangabe schon kennen. Wir können den Pfad mit getName() erfragen.


Rheinwerk Computing - Zum Seitenanfang

15.1.6 Dateien und Verzeichnisse löschenZur vorigen Überschrift

Mithilfe der Methode delete() auf einem File-Objekt lässt sich eine Datei oder ein Verzeichnis entfernen. Diese Methode löscht wirklich! Sie ist nicht so zu verstehen, dass sie true liefert, falls die Datei potenziell gelöscht werden kann. Konnte die Laufzeitumgebung delete() nicht ausführen, so sollte die Rückgabe false sein. Ein zu löschendes Verzeichnis muss leer sein, andernfalls kann das Verzeichnis nicht gelöscht werden. Unsere unten stehende Implementierung geht dieses Problem so an, dass sie rekursiv die Unterverzeichnisse löscht.

class java.io.File
implements Serializable, Comparable<File>
  • boolean delete()
    Löscht die Datei oder das leere Verzeichnis. Falls die Datei nicht gelöscht werden konnte, gibt es keine Ausnahme, sondern den Rückgabewert false.
  • void deleteOnExit()
    Löscht die Datei bzw. das Verzeichnis, wenn die virtuelle Maschine korrekt beendet wird. Einmal vorgeschlagen, kann das Löschen nicht mehr rückgängig gemacht werden. Falls die JVM vorzeitig die Grätsche macht – Reinigungsfachkraft stolpert über Kabel –, kann natürlich die Datei möglicherweise noch immer nicht gelöscht sein, was insbesondere für temporäre Dateien, die über createTempFile() angelegt wurden, eventuell lästig wäre.
Hinweis

Auf manchen Systemen liefert delete() die Rückgabe true, die Datei ist aber nicht gelöscht. Der Grund kann eine noch geöffnete Datei sein, mit der zum Beispiel ein Eingabestrom verbunden ist und die dadurch gelockt ist.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Java ist auch eine Insel





Java ist auch eine Insel
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java ist auch eine Insel






 Java ist auch
 eine Insel


Zum Katalog: Java SE Bibliotheken






 Java SE Bibliotheken


Zum Katalog: Professionell entwickeln mit Java EE 7






 Professionell
 entwickeln mit
 Java EE 7


Zum Katalog: Einstieg in Eclipse






 Einstieg in
 Eclipse


Zum Katalog: Einstieg in Java






 Einstieg in
 Java


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2011
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de