Streaming

Werbung
Ein- und Ausgabe
SYSTEM SOFTWARE
1
Streaming
Streams
Readers und Writers
Objektserialisierung
Dateien
NIO
Zusammenfassung
SYSTEM SOFTWARE
2
Streaming
Ein/Ausgabe und Fluss von Daten
Daten werden nicht auf einmal übertragen, sondern fließen in einem
kontinuierlichen Prozess
Datenquellen – Input – Output – Datensenken
 Eingabestrom verbindet Datenquelle mit Programm
 Ausgabestrom verbindet Programm mit Datensenke
Streams abstrahieren von konkreten Quellen und Senken
 Terminal- oder Konsolenfenster
 Dateien
 Client- und Serverprogramme
 …
InputStream
Programm
Daten
quelle
OutputStream
Daten
senke
SYSTEM SOFTWARE
3
Streaming in Java
Paket java.io
 Byteorientierte Ein- und Ausgabe
 Zeichenorientierte Ein- und Ausgabe
2 Arten von Streams
 Byte-Streams: byte-weises Lesen und Schreiben
 InputStream- und OutputStream-Klassen
 Char-Streams: zeichenweises Lesen und Schreiben (Unicode)
 Reader- und Writer-Klassen
SYSTEM SOFTWARE
4
Basisklasse InputStream
 abstrakte Basisimplementierung, von der konkrete InputStreams abgeleitetet werden
 abstrakte Methode read(), die ein Zeichen liest
 konkrete Implementierungen aller anderen Methoden
 Methoden arbeiten synchron, d.h. blockieren, solange bis Operation abgeschlossen
 Methoden werfen IOExceptions, wenn etwas schief geht
public abstract class InputStream {
public abstract int read() throws IOException
public int read(byte b[]) throws IOException
public int read(byte b[], int off, int len)
throws IOException
public long skip(long n) throws IOException
public int available() throws IOException
public void close() throws IOException
public synchronized void mark(int readlimit)
public synchronized void reset() throws IOException
public boolean markSupported()
}
SYSTEM SOFTWARE
5
Basisklasse OutputStream
 abstrakte Basisimplementierung, von der konkrete OutputStreams abgeleitetet werden
 abstrakte Methode write(), die ein einzelnes Zeichen schreibt
 konkrete Implementierungen aller anderen Methoden
 Methoden arbeiten synchron, d.h. blockieren, solange bis Operation abgeschlossen
 Methoden werfen IOExceptions, wenn etwas schief geht
public abstract class OutputStream {
public abstract void write(int b) throws IOException;
public void write(byte b[]) throws IOException
public void write(byte b[], int off, int len) throws IOException
public void flush() throws IOException
public void close() throws IOException
}
public class IOException extends Exception {
public IOException()
public IOException(String s)
}
SYSTEM SOFTWARE
6
Realisierung von konkreten Stream-Klassen
Ableiten von InputStream bzw. OutputStream
Überschreiben der abstrakten Methoden read bzw. write
Z.B.: FileInputStream: Lesen von Dateien
public class FileInputStream extends InputStream {
public FileInputStream(String name) throws FileNotFoundException
public FileInputStream(File file) throws FileNotFoundException
public native int read() throws IOException
…
}
native implementiert!
Z.B.: FileOutputStream: Schreiben auf Dateien
public class FileOutputStream extends OutputStream {
public FileOutputStream(String name) throws FileNotFoundException
public FileOutputStream(String name, boolean append)
throws FileNotFoundException
public FileOutputStream(File file)
throws FileNotFoundException
public native void write(int b) throws IOException
…
}
native
implementiert!
SYSTEM SOFTWARE
7
Beispiel: Kopieren einer Datei
static void copyFile(String ifile, String ofile) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(ifile);
out = new FileOutputStream(ofile);
int b = in.read();
Man beachte das Abfangen
while (b >= 0) {
der Exceptions
out.write(b);
b = in.read();
}
} catch (FileNotFoundException e) {
System.out.println("File does not exist");
} catch (IOException e) {
System.out.println("Error in reading or writing file");
} finally {
if (in != null) {
try { in.close(); } catch (IOException ioe) {}
}
if (out != null) {
try { out.close(); } catch (IOException ioe) {}
}
}
und Schließen der Streams!!
}
SYSTEM SOFTWARE
8
try-with-resources
try-Anweisung mit Resource-Management
 Erzeugen / Öffnen der Resource
 Verarbeitung
 automatisches Schließen
Resources müssen
AutoClosable implementieren
try ( **** Create resources here **** )
{
**** user resources here ****
} catch ( **** some exceptions **** e) {
...
}
SYSTEM SOFTWARE
Resources automatisch
geschlossen
9
Beispiel: Kopieren einer Datei
Varianten mit try-Anweisung mit Resource-Management
static void copyFile_WithResources(String ifile, String ofile) {
try (
InputStream in = new FileInputStream(ifile);
OutputStream out = new FileOutputStream(ofile)
) {
int b = in.read();
while (b >= 0) {
out.write(b);
b = in.read();
}
Schließen der Streams
} catch (FileNotFoundException e) {
automatisch !!
System.out.println("File does not exist");
} catch (IOException e) {
System.out.println("Error in reading or writing file");
}
}
SYSTEM SOFTWARE
10
Filter-Streams: Überlagern von Streams
FilterStreams sind Streams, die auf einem anderen Stream aufbauen
Ketten von Streams bilden, um
 Basisstreams mit weiterer Funktionalität anzureichern
 Höhere Schnittstellen zur Verfügung zu stellen
Input
Stream
Filter
Input
Stream
Filter
Input
Stream
Prgm
Filter
Output
Stream
Filter
Output
Output
Stream
Stream
Daten
senke
Daten
quelle
InputStream fin = new FileInputStream("input.txt");
BufferedInputStream bin = new BufferedInputStream(fin);
DataInputStream din = new DataInputStream(bin);
OutputStream fout = new FileOutputStream("output.txt");
BufferedOutputStream bout = new BufferedOutputStream(fout);
DataOutputStream dout = new DataOutputStream(bout);
SYSTEM SOFTWARE
11
FilterStreams: BufferedInputStream - BufferedOutputStream
Gepufferte Eingabe: BufferedInputStream
 Effizienz durch Vorauslesen
File ifile = new File(“inputfile.txt”);
InputStream in = new BufferedInputStream(
new FileInputStream(ifile));
Gepufferte Ausgabe: BufferedOutputStream
 Effizienz durch verzögertes Schreiben
 Tatsächliche Ausgabe erst wenn Puffer voll
 Methode flush erzwingt Ausgabe des Puffers
File ofile = new File(“outputfile.txt”);
OutputStream out = new BufferedOutputStream(
new FileOutputStream(ofile));
SYSTEM SOFTWARE
12
FilterStreams: DataInputStream, DataOutputStream
Ausgabe primitiver Datentypen
public class DataOutputStream
extends FilterOutputStream {
void writeBoolean(boolean v);
void writeByte(int v);
void writeBytes(String s);
void writeChar(int v);
void writeChars(String s);
void writeDouble(double v);
void writeFloat(float v);
void writeInt(int v);
void writeLong(long v);
void writeShort(int v);
void writeUTF(String str);
...
}
public class DataInputStream
extends FilterInputStream {
boolean readBoolean();
byte
readByte();
char
readChar();
double readDouble();
float
readFloat();
int
readInt();
long
readLong();
short
readShort();
int
readUnsignedByte();
int
readUnsignedShort();
String readUTF();
...
}
File fout = new File("output.data");
DataOutputStream out = new DataOutputStream(
new FileOutputStream(fout));
out.writeDouble(Math.PI);
out.close();
SYSTEM SOFTWARE
output:
0x40 0x09 0x21 0xfb
0x54 0x44 0x2d 0x18
;
;
@.!û
TD-.
13
InputStream Klassenhierarchie
Auszug!
PipedInputStream
BufferedInputStream
SequenceInputStream
InputStream
CheckedInputStream
FileInputStream
DigestInputStream
FilterInputStream
ZipInput
Stream
JarInput
Stream
InflaterInputStream
StringBufferInputStream
LineInputStream
GZIPInput
Stream
ByteArrayInputStream
PushBackInputStream
ObjectInputStream
DataInputStream
<<interface>>
ObjectInput
<<interface>>
DataInput
SYSTEM SOFTWARE
14
OutputStream Klassenhierarchie
Auszug!
PipedOutputStream
BufferedOutputStream
OutputStream
FileOutputStream
CheckedOutputStream
DigestOutputStream
FilterOutputStream
ZipOutput
Stream
JarOutput
Stream
DeflaterOutputStream
ByteArrayOutputStream
PrintStream
GZIPOutput
Stream
DataOutputStream
ObjectOutputStream
<<interface>>
ObjectOutput
<<interface>>
DataOutput
SYSTEM SOFTWARE
15
Diverse Streamklassen
public class PipedOutputStream
extends OutputStream {
void connect(PipedInputStream snk);
...
}
• Realisierung von Pipes
public class PipedInputStream
extends InputStream {
void connect(PipedOutputStream src);
...
}
public class PushbackInputStream
extends InputStream {
int read();
void unread(int b);
...
}
• unterstützt Zurückschreiben
(unread)
public class PrintStream
extends FilterOutputStream {
public void print(boolean b)
public void print(int b)
…
public void println(boolean b)
…
}
• formatierte Ausgabe von Daten
• mittels print und printlnMethoden
SYSTEM SOFTWARE
16
Standardstreams
Streams in der Klasse System
static InputStream in;
static PrintStream out;
static PrintStream err;
// the standard input stream
// the standard output stream
// the standard error stream
Filtern der Standardstreams
BufferedReader input =
new BufferedReader(
new InputStreamReader(System.in));
String line = input.readLine();
Umleiten der Standardstreams
java Foo < input.txt > output.txt 2> error.txt
oder
java Foo > output.txt 2>&1
oder
java Foo >> output.txt
SYSTEM SOFTWARE
17
Hierarchie der Ausnahmen
Auszug!
Exception
ClassNotFoundException
IOException
FileNotFoundException
EOFException
ObjectStreamException
NotSerializableException
SYSTEM SOFTWARE
18
Streaming
Streams
Readers und Writers
Objektserialisierung
Dateien
NIO
Zusammenfassung
SYSTEM SOFTWARE
19
Zeichenorientierte Ein- und Ausgabe
Ein- und Ausgabe von char-Daten über Readers und Writers
Basisklassen
 Reader (abstrakte Basisklasse analog zu InputStream)
 Writer (abstrakte Basisklasse analog zu OutputStream)
Datenkonvertierung
 Abbildung von Zeichen auf Bytes erforderlich (Dateien sind byteorientiert)
 FileReader und FileWriter verwenden Standardcodierung
 Andere Codierungen mittels InputStreamReader und OutputStreamWriter
bzw. Character Sets
Writer out = new OutputStreamWriter(
new FileOutputStream("fname"),
"UTF8"
// encoding parameter
);
SYSTEM SOFTWARE
20
Basisklasse Reader
Abstrakte Basisimplementierung, von der konkrete Reader abgeleitetet werden
Abstrakte Methode
read(char[] cbuf, int off, int len)
welche einen char-Array schreibt
Andere Methoden bauen auf dieser auf
public abstract class Reader {
public int read() throws IOException
public int read(char[] cbuf) throws IOException
public abstract int read(char[] cbuf, int off, int len)
throws IOException
public long skip(long n) throws IOException
public boolean ready() throws IOException
public synchronized void mark(int readlimit)
public synchronized void reset() throws IOException
public boolean markSupported()
public abstract void close() throws IOException
}
SYSTEM SOFTWARE
21
Basisklasse Writer
Abstrakte Basisimplementierung, von der konkrete Writer abgeleitetet werden
Abstrakte Methode
write(char[] cbuf, int off, int len)
welche einen char-Array füllt
Andere Methoden bauen auf dieser auf
public abstract class Writer {
public void write(int c) throws IOException
public void write(char[] cbuf) throws IOException
public abstract void write(char[] cbuf, int off, int len)
throws IOException
public void write(String str) throws IOException
public void write(String str, int off, int len)
throws IOException
public abstract void flush() throws IOException
public abstract void close() throws IOException
}
SYSTEM SOFTWARE
22
BufferedReader - PrintWriter
Zeilenweises lesen mit readLine
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
try {
line = reader.readLine();
} catch (IOException ioe) {
ioe.printStackTrace();
}
Schreiben mit print
PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out));
try {
writer.println(line);
writer.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
SYSTEM SOFTWARE
23
Reader Klassenhierarchie
Auszug!
PipedReader
Reader
InputStreamReader
FileReader
FilterReader
PushbackReader
StringReader
CharArrayReader
BufferedReader
SYSTEM SOFTWARE
LineNumberReader
24
Diverse Reader
public class InputStreamReader extends Reader{
public InputStreamReader(InputStream in)
...
}
• Brücke zu InputStream
public class LineNumberReader extends Reader {
int getLineNumber();
...
}
• Zugriff auf Zeilennummern
public class BufferedReader extends Reader {
public String readLine() throws IOException
...
}
• gepufferte Eingabe
• unterstützt zeilenweises
Lesen (readLine)
public class PushbackReader extends Reader {
public void unread(char[] cbuf,
int off, int len) throws IOException
...
}
• unterstützt Zurückschreiben
(unread)
public class PipedReader extends Reader {
public void connect(PipedWriter src)
throws IOException
…
}
• Realisierung von Pipes
• in Kombination mit
PipedWriter
SYSTEM SOFTWARE
25
Writer Klassenhierarchie
Auszug!
PipedWriter
OutputStreamWriter
Writer
FileWriter
FilterWriter
StringWriter
CharArrayWriter
BufferedWriter
PrintWriter
SYSTEM SOFTWARE
26
Diverse Writer
public class OutputStreamWriter extends Writer
• Brücke zu OutputStream
public OutputStreamWriter (OutputStream out)
...
}
public class PrintWriter extends Writer {
public void print(boolean b)
public void print(int b)
…
public void println(boolean b)
…
}
public class BufferedWriter extends Writer {
public void newLine() throws IOException
public void flush() throws IOException
...
}
public class PipedWriter extends Writer {
public void connect(PipedReader snk)
throws IOException
…
}
SYSTEM SOFTWARE
• formatierte Ausgabe von Daten
als Text
• mittels print und printlnMethoden
• gepufferte Ausgabe
• unterstützt neue Zeile
(newLine)
• Realisierung von Pipes
• in Kombination mit
PipedReader
27
Streaming
Streams
Readers und Writers
Objektserialisierung
Dateien
NIO
Zusammenfassung
SYSTEM SOFTWARE
28
Serialisierung von Objekten
Speichern des Zustands von Objekten
 Plattformunabhängige Transformation in Bytes
 Verwendung für Speicherng von Objekten, Kommunikation von Programmen
Serialisierung
 Klasse muss Serializable implementieren
 Automatische Serialisierung der Felder
 Transitive Hülle
 Objekte die über Referenzen in Feldern erreichbar sind, werden ebenfalls serialisiert
 in Form eines Objektgraphen (und nicht eines Baums)
 Keine Serialisierung „transienter“ Felder
public class ObjectOutputStream {
void writeBoolean(boolean data);
...
void writeObject(Object obj);
}
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data"));
Person p = ...;
out.writeObject(p);
SYSTEM SOFTWARE
29
Serializable
Nur Objekte, die Serializable implementieren, können serialisiert werden
Damit werden alle Felder, die serialisierbar sind, automatisch mit dem Objekt
serialisiert
 Felder mit Basisdatentypen
 Felder mit Typen, die serialisierbar sind
Kennzeichnet man Felder mit transient, werden diese nicht serialisiert !!
 Verhinderung der Serialisierung von bestimmten Werten
 Felder mit Werte, die nicht serialisierbar sind, müssen transient markiert werden
 sonst NotSerializableException
public interface Serializable { }
public class Person implements Serializable {
private String name;
private int age;
private List<Person> children;
private transient List<PropertyChangeListener> listener;
}
SYSTEM SOFTWARE
30
Serialisierbare / Nicht-serialisierbare Datentypen
Serialisierbar:
 Basisdatentypen (int, boolean, double, …)
 Alle Arrays
 String
 Collections: ArrayList, LinkedList, TreeSet, …
 Calendar, Date, etc.
 Alle weiteren Typen, die Serializable implementieren
Beispiel nicht serialisierbarer Werte:
 Thread, ClassLoader, etc.
 Objekte der Java-VM
 InputStream, Socket, etc.
 Objekte, die auf Betriebssystemressourcen zugreifen
 und andere
SYSTEM SOFTWARE
31
Serialisierung von Objektgraphen
Kunde
Name = Max
Bank
Konto
Konto
Name = SSW
Konten
Betrag = € 100
Besitzer
Next
Betrag = € 500
Besitzer
Next
Mehrere Referenzen auf das selbe Objekt:
 1. Besuch: Objekt vollständig schreiben
 weiterer Besuch: nur ID des Objekts schreiben
(Bank)
"SSW"
(Konto)
€ 100
(Kunde)
"Max"
SYSTEM SOFTWARE
(Konto)
€ 500
(Kunde)
878
32
Deserialisierung
Einlesen eines Objekts
 Allokation von Speicher und Initialisierung
 ClassNotFoundException falls Klasse nicht vorhanden
 Einlesen des Objekts
 Transiente Felder erhalten Standardwert
public class ObjectInputStream {
boolean readBoolean();
byte
readByte();
...
Object readObject();
...
}
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data"));
Person p = (Person) in.readObject();
SYSTEM SOFTWARE
33
Serialisierungsformat
public class Person implements Serializable {
private String name;
private int age;
}
Serialisierung enthält
 vollständige Typinformation
 Versionsnummer
Person hans = new Person("Hans", 26);
 Daten
AC
73
72
EB
00
L
74
I
78
70
74
00
ED
00
A3
02
00
00
00
00 05
06 Person
AE 56 EF 40 EE 9B
02
04 name
12 Ljava/lang/String
03 age
00 04 Hans
00 00 00 00 1A
Dateikennzeicheb und Version der Serialisierung
73 für neues Objekt
72 für Klasse, Länge des Klassennamens, Klassenname
Serial UID, Flag für implements Serializable
Anzahl der Felder
L für Feldtyp Klasse, Länge Feldnamen, Feldname
74 für Typbezeichner, Länge Typname, Typename
I für Feldtyp int, Länge Typname, Typename
78 Ende der Feldbeschreibungen
70 Keine Superklasse
Daten Feld name
3 Byte Daten für Feld age
SYSTEM SOFTWARE
34
Benutzerdefinierte Serialisierung (1/3)
Anpassung der Serialisierung durch Implementierung von Methoden
writeObject und readObject
private void writeObject(ObjectOutputStream stream) throws IOException;
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException;
class LabeledPoint implements Serializable {
private String label;
private transient Point2D.Double point;
...
private void writeObject(ObjectOutputStream out)
throws IOException {
out.defaultWriteObject();
out.writeDouble(point.x);
out.writeDouble(point.y);
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
double x = in.readDouble();
double y = in.readDouble();
point = new Point2D.Double(x, y);
}
}
SYSTEM SOFTWARE
Point2D nicht serialisierbar
 transient
Standard-Serialisierung
aller anderen Felder inkl.
Superklasse
Serialisierung der Daten
des transienten Feldes
Standard-Deserialisierung
Deserialisierung der Daten
des transienten Feldes
Rekonstruktion des transienten
Feldes
35
Benutzerdefinierte Serialisierung (2/3)
Eigene Serialisierung durch Implementierung des Interfaces Externalizable
public interface Externalizable extends java.io.Serializable {
void writeExternal(ObjectOutput out) throws IOException;
void readExternal(ObjectInput in) throws IOException,ClassNotFoundException;
}
 Serialisierung muss vollständig implementiert werden
 Nur Identität der Klasse wird automatisch gespeichert
 Verwendet und fordert Standard-Konstruktor (ohne Parameter)
class LabeledPoint implements Externalizable {
...
public LabeledPoint() { }
Standard-Konstruktor gefordert
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(label);
Schreiben der Daten in
out.writeDouble(point.x);
out.writeDouble(point.y);
writeExternal
}
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
label = in.readUTF();
double x = in.readDouble();
double y = in.readDouble();
point = new Point2D.Double(x, y);
}
Lesen der Daten und
Setzen der Felder
}
SYSTEM SOFTWARE
36
Benutzerdefinierte Serialisierung (3/3)
Ersetzen durch ein anderes Objekt: writeReplace und readResolv
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;

writeReplace wird vor dem Schreiben aufgerufen

readResolve wird nach dem Lesen aufgerufen
Beispiel: Lesen von Objekten und Ersetzen durch Singleton-Objekt
class Orientation implements Serializable {
public static final Orientation HORIZONTAL = new Orientation(1);
public static final Orientation VERTICAL = new Orientation(2);
private int value;
private Orientation(int value) {
this.value = value;
}
protected Object readResolve() throws ObjectStreamException {
if (value == 1) return Orientation.HORIZONTAL;
if (value == 2) return Orientation.VERTICAL;
Nach Deserialisierung des Objekts
return null;
wird Singleton-Objekt zurückgegeben!
}
}
Achtung: Serialisierung von Enum-Werten funktioniert automatisch!!
SYSTEM SOFTWARE
37
Versionsverwaltung (1/2)
Problem: Kompatibilität von serialisierten Objekten mit neuen Versionen
von Klassen
 bei Serialisierung wird mit Klasse eindeutige UID gespeichert

Hash-Code (SHA) aus Klassendefinition
 Ändert sich Klasse, wird beim Lesen Objekt als inkompatibel erkannt

 Objekt kann nicht mehr gelesen werden!
 Oft ist aber eine neue Klasse kompatibel zur alten Version, weil z.B. nur Methoden und
keine Felder verändert wurden
SYSTEM SOFTWARE
38
Versionsverwaltung (2/2)
Abhilfe:
 Durch Setzen der serialVersionUID im Quellcode
 wird bei Serialisierung UID nicht mehr berechnet
 sondern die Nummer aus Quellcode entnommen
Vorgehen:
 Bestimmen der UID der alten Version mit Tool serialver
 Setzen der gleichen UID als serialVersionUID in Quellcode der neuen Version
public class Person implements Serializable {
private static final long serialVersionUID = 213554356225514906L;
…
Damit wird neue Version als kompatibel zur alten Version erkannt
 Eventuell spezifische Lesemethoden (readExternal), um neue Objekte aus alten
serialisierten Daten zu erzeugen
SYSTEM SOFTWARE
39
Streaming
Streams
Readers und Writers
Objektserialisierung
Dateien
NIO
Zusammenfassung
SYSTEM SOFTWARE
40
File
Abstrakte Repräsentation einer Datei oder eines Verzeichnisses
 Konstruktor greift noch nicht auf Dateisystem zu
Definiert plattformspezifische Trennzeichen
 separator und pathSeparator
Erzeugen von Dateiströmen
 Mittels Dateinamen oder File-Objekt
public class File {
boolean canRead();
boolean canWrite();
boolean delete();
boolean exists();
String
getName()
boolean isDirectory();
boolean isFile();
long
lastModified();
long
length();
String[] list();
File[]
listFiles();
...
}
static long totalSize(File dir) {
if (!dir.isDirectory()) {
return -1;
}
long size = 0;
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
size += files[i].length();
}
return size;
}
SYSTEM SOFTWARE
41
Streaming
Streams
Readers und Writers
Objektserialisierung
Dateien
NIO
Zusammenfassung
SYSTEM SOFTWARE
42
NIO
Mit NIO und NIO.2 gibt es neue Klassen für Dateimanagement und
Dateiein- und ausgabe
Packages
 java.nio.files
Path und Files für Dateimanagement
 java.nio.channel
Channels für gepufferte und asynchrone Ein/Ausgabe
 java.nio.charset
Charset für Kodierung von Unicode
SYSTEM SOFTWARE
43
Path (1/2)
Path ist Klasse für Dateipfade
 repräsentiert einen Pfad (und noch keine Datei)
 stellt Methoden für die Manipulation von Pfaden dar
Paths mit statischen Methoden get, um Pfad zu erstellen
private static final String SRC = "C:\\Users\\hp\\Java\\src";
Path srcPath = Paths.get(SRC);
Path nioRelPath = Paths.get("nio");
Path javaFilePath = Paths.get(SRC, "nio", "PathDemo.java");
absoluter Pfad
relativer Pfad
Path stellt dann Methoden für den Umgang mit Pfaden bereit

resolve: neuer Pfad aus this und (relativem) Argumentpfad
Path nioAbsPath = srcPath.resolve(nioRelPath);

relativize: relativer Pfad um von this zum this und (relativer) anderer
Path javaRelPath = srcPath.relativize(javaFilePath);
 normalize: eliminiert redundante Teilpfade
Path homePath = Paths.get("C:\\Users\\hp\\..\\..\\Users\\hp");
Path homePathNorm = homePath.normalize();
SYSTEM SOFTWARE
44
Path (2/2)
 Zugriff auf Teile eines Pfades
 über Iterator
C:\
Users
hp
Java
nio
PathDemo.java
for (Path p : javaFilePath) {
println(p);
}
 oder mit indiziertem Zugriff
javaFilePath.get(0));
C:\
 letzter Teil (Datei- oder Verzeichnisname)
println(javaFilePath.getFileName());
PathDemo.java
 Zugriff auf Eigenschaften
println(thisFilePath.endsWith("PathDemo.java"));
println(thisFilePath.startsWith("C:\\"));
true
true
 uvm.
SYSTEM SOFTWARE
45
Files (1/3)
Files mit statischen Methoden, um auf Dateisystem zuzugreifen und
Dateien zu manipulieren
 Abfrage, ob Datei oder Verzeichnis mit Pfad existiert und Erzeugen
if (! Files.exists(javaFilePath)) {
Files.createFile(javaFilePath);
}
if (! Files.exists(nioPath)) {
Files.createDirectory(nioPath);
}
 Dateien kopieren, verschieben, löschen
beliebig viele Options !
Files.copy(javaFilePath, javaCopyPath,
StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);
Files.move(javaFilePath, javaCopyPath, StandardCopyOption.REPLACE_EXISTING);
Files.delete(javaFilePath);
Files.deleteIfExists(javaFilePath);
SYSTEM SOFTWARE
46
Files (2/3)
Files lesen und schreiben
 lines
Files.lines(javaFilePath).forEach(line -> {
println(line);
});
Stream-Zugriff ist lazy!
 realdAllLines
List<String> lines = Files.readAllLines(javaFilePath);
for (String line : lines) {
println(line);
}
Zugriff auf Input/Outputstreams
BufferedReader r = Files.newBufferedReader(javaFilePath);
BufferedWriter w = Files.newBufferedWriter(javaFilePath);
SYSTEM SOFTWARE
47
Files (3/3)
 Zugriff auf Attribute
beliebig viele Options !
FileTime lastModified = Files.getLastModifiedTime(javaFilePath);
println(lastModified);
2016-04-10T09:11:23.131982Z
long size = (long)Files.getAttribute(javaFilePath, "size");
println(size);
FileTime now =
FileTime.fromMillis(System.currentTimeMillis());
Files.setLastModifiedTime(javaFilePath, now);
Zugriff auf alle Attribute !
BasicFileAttributeView Attribute
Name
"lastModifiedTime"
"lastAccessTime"
"creationTime"
"size"
"isRegularFile"
"isDirectory"
"isSymbolicLink"
"isOther"
"fileKey"
Type
FileTime
FileTime
FileTime
Long
Boolean
Boolean
Boolean
Boolean
Object
BasicFileAttributeView attrs =
Files.getFileAttributeView(javaFilePath, BasicFileAttributeView.class);
attrs.setTimes(now, now, now);
SYSTEM SOFTWARE
48
Iteration über Files
walk: Stream von Pfaden eines Verzeichnisses
Path root = Paths.get(SRC);
try (Stream<Path> paths = Files.walk(root, 3)) {
paths.forEach(p -> {
println(p.toString());
});
Stream erzeugen als closable Ressource !
Zugriff auf Stream lazy !
}
C:\Users\hp\Java
C:\Users\hp\Java\nio
C:\Users\hp\Java\nio\FileDemo.java
...
PathMatcher: Suchen von Files über Glob
PathMatcher javaMatcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
if (javaMatcher.matches(javaFilePath)) println("It‘s a Java file");
PathMatcher javaMatcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
try (Stream<Path> paths = Files.walk(root)) {
paths.forEach(p -> {
if (javaMatcher.matches(p)) {
println(p.toString());
}
});
}
SYSTEM SOFTWARE
49
Walk über Verzeichnisbaum
walkFileTree:
Visitor über
Verzeichnisbaum
public interface FileVisitor<T> {
FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) throws IOException;
FileVisitResult visitFile(T file, BasicFileAttributes attrs) throws IOException;
FileVisitResult visitFileFailed(T file, IOException exc) throws IOException;
FileVisitResult postVisitDirectory(T dir, IOException exc) throws IOException;
}
Files.walkFileTree(root, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
printfln(indent + "START %s ------", dir.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
printfln(indent + "FILE %s", file.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
printfln(indent + "++ FAILED %s", file.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
printfln(indent + "END %s --------", dir.toString());
return FileVisitResult.CONTINUE;
}
});
SYSTEM SOFTWARE
50
WatchService (1/3)
Beobachten Änderungen in Verzeichnis
WatchService watcher = FileSystems.getDefault().newWatchService();
FileWatcher für FileSystem
erzeugen !
Path root = Paths.get(SRC);
try (Stream<Path> paths = Files.walk(root)) {
paths.forEach(p -> {
if (Files.isDirectory(p)) {
try {
p.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
} catch (Exception e) {
}
Verzeichnis beim Watcher
}
registrieren
});
}
...
SYSTEM SOFTWARE
51
WatchService (2/3)
Beobachten Änderungen in Verzeichnissen
watcherThread = new Thread( () -> {
in eigenem Thread
while (! stopWatcher) {
try {
WatchKey zugreifen  blockierend!
WatchKey k = watcher.take();
for (WatchEvent<?> evt: k.pollEvents()) {
WatchEvent<Path> pevt = (WatchEvent<Path>) evt;
Über Events iterieren
Path relPath = pevt.context();
Path dir = (Path)k.watchable();
Path absPath = dir.resolve(relPath);
Events behandeln
printfln("CHANGE %s:", pevt.kind().toString());
printfln("
dir: %s", dir.toString());
printfln("
relative: %s, absolute: %s", relPath.toString(), absPath.toString());
if (Files.isDirectory(absPath)) {
if (pevt.kind() == ENTRY_CREATE) {
try {
absPath.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
} catch (Exception e) {
neues Verzeichnis beim Watcher
}
registrieren
}
}
}
k.reset();
nach Behandlung WatchKey reseten (sonst nur
} catch (InterruptedException e) {
einmal pro Registrierung aktiv)
}
}
});
watcherThread.start();
SYSTEM SOFTWARE
52
WatchService (3/3)
Zusammenfassung der Zugriffe
 Erzeugen eines FileWatchers global für FileSystem
WatchService watcher = FileSystems.getDefault().newWatchService();
 Registrieren von Verzeichnis
dirPath.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
 Warten und Zugriff auf Änderungen  WatchKey
WatchKey k = watcher.take();
 WatchKey erlaubt Zugriff auf Ereignisse
 Ereignisse und Pfad des Ereignises
for (WatchEvent<?> evt: k.pollEvents()) {
WatchEvent<Path> pevt = (WatchEvent<Path>) evt;
Path relPath = pevt.context();
 Verzeichnis, in dem Ereignis aufgetreten ist
Path dir = (Path)k.watchable();
 Reset des WatchKey, wenn Verzeichnis weiter beobachtet werden soll
k.reset();
oder cancel, wenn nicht
k.cancel();
SYSTEM SOFTWARE
53
Character Sets
in java.nio.charset
Charset Klasse für Character-Kodierung

Erzeugen eines Charset-Objekts mit statischer Methode forName
und Namen der Kodierung
Charset cset = Charset.forName("UTF-8");

Kodierung mit ByteBuffers
String original = "...";
ByteBuffer buffer = cset.encode(original);
byte[] bytes = buffer.array();

Decodierung über ByteBuffers und CharBuffers
ByteBuffer bbuf = ByteBuffer.wrap(bytes);
CharBuffer cbuf = cset.decode(bbuf);
String decoded = cbuf.toString();
Verwendung von Charset bei Reader und Writer
Writer out = new OutputStreamWriter(new FileOutputStream("fname.txt"), cset);
Reader in = new InputStreamReader(new FileInputStream("fname.txt"), cset);
SYSTEM SOFTWARE
54
Streaming
Streams
Readers und Writers
Objektserialisierung
Dateien
NIO
Zusammenfassung
SYSTEM SOFTWARE
55
Zusammenfassung
Datenströme
 Verbinden Datenquelle mit Programm oder Programm mit Datensenke
Byteorientierte Datenströme
 InputStream und OutputStream
 FileInputStream und FileOutputStream
Zeichenorientierte Datenströme
 Reader und Writer
Gepufferte Datenströme
 BufferedInputStream und BufferedOutputStream
 BufferedReader und BufferedWriter
Serialisierung
 Plattformunabhängige Transformation des Objektgraphen in Bytes
NIO
 Neue mächtige Konzepte für Dateimanagement und Ein/Ausgabe
SYSTEM SOFTWARE
56
Herunterladen