Betriebssysteme Wintersemester 2013 Kapitel 4 – Ein- / Ausgabe und Dateisysteme Patrick Kendzo [email protected] Programm Inhalt Einleitung Prozesse und Threads Speicherverwaltung Ein- / Ausgabe und Dateisysteme Klausurvorbereitung 2 Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (1) Es existieren zwei Arten der Ein- und Ausgabe: 3 1) Zwei-Dimensional • EA zu Bildschirm über Tastatur / Maus für menschliche BenutzerInnen 2) Ein-Dimensional ( Wird in dieser Vorlesung behandelt ) • Datenströme (nach Wasserschlauch-Modell) • DOS Fenster • Dateien • Speicher • Prozesskommunikation • Rechnernetz Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (2) Ein-/Ausgabe aus Java-Perspektive: Ein- und Ausgabeklasse aus Java sind sowohl für Byte als auch für Zeichen geeignet • Dafür steht unterschiedliche Klasse zur Verfügung Die Programmierung ist unabhängig von Quelle oder Senke. Am Beispiel von: • DOS Fenster • Dateien • Speicher • Prozesskommunikation • Rechnernetz Java nutzt folgende Filtertechnik (Verarbeitung der Daten nach dem Schreiben bzw. vor dem Lesen) • Kompression und Pufferung • Ver- und Entschlüsselung 4 Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (3) Übersicht der Java EA-Klasse: 5 Es existieren zwei Kategorien von Klassen • Byteorientierte (blockorientierte) Klassen (Byte Streams) • Zeichenorientierte Klassen (Character Streams) Sowohl Byteströme als auch Zeichenströme werden in Klassen: • ohne Verarbeitung der Daten (Data Sink Streams) • mit Verarbeitung der Daten (Procession Streams) unterteilt Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (4) Übersicht der Java EA-Klasse (continued): 6 Byte-Klassen Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (5) Übersicht der Java EA-Klasse (continued): 7 Zeichen-Klassen Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (6) Byte-Klassen: InputStream / OutputStream: Beschreibung der abstrakten Klasse: InputStream Besitzt einen Konstruktor ohne Argumente (Dient dem automatischen Öffnen des Stroms) int read(); o o int read(byte[] buf); o 8 Einlesen der Werte 0 bis 255; Am Ende des Stroms Rückgabewert = -1 Einlesen der Byte-Werte: -127 bis +128; Am Ende des Stroms Rückgabewert=-1 int read(byte[] buf, int offset, int len); int skip(long count); int available(); Anzahl der Bytes, die gelesen werden können, ohne zu blockieren void close(); Automatisches Schließen erfolgt beim Löschen des Objekts Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (7) Byte-Klassen: InputStream / OutputStream (continued): Beschreibung der abstrakten Klasse: OutputStream 9 Besitzt einen Konstruktor ohne Argumente (Dient dem automatischen Öffnens des Stroms) int write(int b); Zum Schreiben von Werten int write(byte[] buf); int write(byte[] buf, int offset, int len); int flush(); // Hiermit kann der Puffer eines Stroms geleert werden. D.h. Daten werden “weggeschrieben”. void close(); Automatisches Schließen erfolgt beim Löschen des Objekts Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (8) Byte-Klassen: FileInputStream / FileOutputStream: Diese Klasse werden zum byteweisen Lesen und Schreiben von Dateien eingesetzt FileInputStream (aus InputStream abgeleitet) 10 Besitzt einen Konstruktor mit einem String-Argument(Dateiname) Datei muss existieren; Sonst Ausnahme Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (9) Byte-Klassen: FileInputStream / FileOutputStream: 11 FileOutputStream (aus OutputStream abgeleitet) 1) Besitzt einen Konstruktor mit einem String-Argument(Dateiname) Falls Datei nicht vorhanden ist, wird sie neu erzeugt Falls Datei vorhanden ist, so wird bisheriger Inhalt gelöscht (vor dem ersten Schreiben) 2) Besitzt einen Konstruktor mit einem String-Argument(Dateiname) und boolean-Argument Falls Datei nicht vorhanden ist, wird sie auch neu erzeugt Falls Datei vorhanden ist, so wird bisheriger Inhalt gelöscht (zweites Argument false) oder es wird an den bisherigen Inhalt angehängt (zweites Argument true) Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (10) Beispiel: import java.io.*; public class CopyBytes{ public static void main(String[] args) throws IOException { if(args.length != 2){ System.out.println("usage: java bs.CopyBytes " + "<input file name> <output file name>"); return; } FileInputStream in = new FileInputStream(args[0]); FileOutputStream out = new FileOutputStream(args[1]); int c; int bytes = 0; while((c = in.read()) != -1){ out.write(c); bytes++; } in.close(); out.close(); } } 12 Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (11) Filterströme: 13 Konzept Filterströme werden stapelweise genutzt, um Nutzdaten zu verarbeiten Filtereingabestrom liest Daten von einem bereits existierenden Eingabestrom und verändert diese, bevor die Anwendung sie liest Filterausgabestrom verändert die von der Anwendung übergebenen Daten, bevor sie in einen bereits existierenden Ausgabestrom geschrieben werden Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (12) Filterströme (continued): Metapher: Wasserfilter Filter an einem Wasserhahn (Eingabe) Filter an einem Schlauch, in den Wasser hineingepumpt wird (Ausgabe) Beachte: Metapher nur bedingt geeignet, da diese Filter nur etwas wegnehmen (ausfiltern) können – Keine Modifikation erfolgt In Java können beliebig Daten verarbeitet werden: 14 Datenformatwandlung Puffern Kompression / Dekompression Verschlüsselung / Entschlüsselung Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (13) Filterströme (continued): 15 Filterklassen haben Konstruktoren mit einem Argument vom Typ derselben Basisklasse: Konstruktor von FilterInputStream besitzt Argument des Typs InputStream Konstruktor von FilterOutputStream besitzt Argument des Typs OutputStream Ein Filterobjekt benutzt den im Konstruktor angegebenen Strom zum Lesen bzw. Schreiben, fügt aber weitere Funktionalität hinzu Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (14) Filterströme (continued): Konkrete Filterklassen innerhalb der byteweisen EA (abgeleitet aus FilterInputStream bzw. FilterOutputStream): Puffern: BufferInputStream, BufferOutputStream: o Puffern der Daten, um Zugriffe auf die angeschlossene Quelle bzw. Senke zu reduzieren o i.d.R. effizienter als ungepufferter Zugriff o Konstruktoren: 1. 2. 3. 4. 16 BufferedInputStream(InputStream in); BufferedInputStream(InputStream in, int bufferSize); BufferedOutputStream(OutputStream out); BufferedOutputStream(OutputStream out, int bufferSize); Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (15) Filterströme (continued): Konkrete Filterklassen innerhalb der byteweisen EA (continued): Binäre EA primitiver Daten: DataInputStream, DataOutputStream: o Spezielle Methoden zum Lesen / Schreiben von primitiven Daten: short, int, long, float, double etc… o Konstruktoren: 1. 2. o Methoden von DataInput- und DataOutputStream: o 17 DataInputStream(InputStream in); DataOutputStream(OutputStream out); boolean readBoolean(); byte readByte(); … void writeBoolean(boolean b); void writeByte(int b); … Siehe Java Documentation für eine komplette Auflistung Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (16) Filterströme (continued): Konkrete Filterklassen innerhalb der byteweisen EA (continued): Eingabestrom mit der Möglichkeit, gelesene Bytes in den Eingabestrom zurückzusetzen (so, als wären sie noch nicht gelesen worden): PushbackInputStream o Konstruktoren: 1. 2. o Methoden von PushbackInputStream: 18 PushbackInputStream(InputStream in); PushbackInputStream(InputStream in, int size); (size: Größe, wie viele Zeichen zurückgegeben werden können – Standard = 1) void unread(int b); void unread(byte[] b); void unread(byte[] b, int offset, int length); Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (17) Filterströme (continued): Konkrete Filterklassen innerhalb der byteweisen EA (continued): Ausgabestrom mit Wandlung von primitiven Datentypen in ASCIIBytes (7-Bit-Zeichencodierung): PrintStream: o Bequemere Nutzung als andere Ausgabemethoden, da Ausnahmen in den Methoden abgefangen werden o Konstruktoren: o Methoden von PrintStream: 19 PrintStream(OutputStream out); PrintStream(OutputStream out, boolean autoFlush); autoFlush: Automatisches Flush beim Schreiben von „Newline“ oder beim Schreiben eines Byte-Felds (Standard: true) void print(boolean b); void print(char c); void print(char[] c); … Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (18) Filterströme (continued): Weitere Beispiele: Kompression (Package java.util.zip): InflaterInputStream, DeflaterOutputStream Verschlüsselung, Entschlüsselung (Package javax.crypto): CipherInputStream, CipherOutputStream Eigene Fliterklassen können entwickeln und in Java integriert werden Beispiele für eigene Filterklassen: 1. 2. 20 Nicht druckbare Bytes durch Ausgabe '?' ersetzen (für Ein- und Ausgabe möglich) N-Stück: Duplizierung eines Ausgabestroms auf mehrere Ausgabeströme Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (18) Byteweise Ein-/Ausgabe im Hauptspeicher: Durch Nutzung der Klassen PipedInputStream bzw. PipedOutputStream: Kommunikationskanal zwischen Threads PipedInputStream und PipedOutputStream müssen miteinander gekoppelt werden Konstruktoren: 1. 2. 3. 4. 21 PipedInputStream(); PipedInputStream(PipedOutputStream source); PipedOutputStream(); PipedOutputStream(PipedInputStream sink); Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (19) Zeichen-Klassen: Reader/ Writer: Beschreibung der abstrakten Klasse: Reader Besitzt einen Konstruktor ohne Argumente int read(); o int read(char[] buf); o 22 Am Ende des Stroms Rückgabewert = -1 Am Ende des Stroms Rückgabewert=-1 int read(char[] buf, int offset, int length); int skip(long count); boolean ready(); true, falls nächster read-Aufruf nicht blockiert void close(); Automatisches Schließen erfolgt beim Löschen des Objekts Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (20) Zeichen-Klassen : Reader/ Writer: Beschreibung der abstrakten Klasse: Writer 23 Besitzt einen Konstruktor ohne Argumente int write(int c); int write(char[] buf); int write(char[] buf, int offset, int length); void write(String string); void write(String string , int offset, int length); void flush(); void close(); Automatisches Schließen erfolgt beim Löschen des Objekts Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (21) Zeichen-Klassen : Reader/ Writer (continued): Bei der Nutzung der konkreten Klasse findet eine Wandlung zwischen Bytes und Zeichen statt InputStreamReader (aus Reader abgeleitet): Bytes werden aus einem InputStream gelesen und als Zeichen an die Anwendung weitergegeben Kodierung der Eingabebytes: Standard oder durch Namen Beispiele von Kodierungen: 1. "8859_1": ASCII und Umlaute (u.a.) 2. "Unicode" 3. "UTF8“ 4. Kodierung lesen: String getEncoding(); Konstruktoren: 1. 2. 24 … InputStreamReader(InputStream in); InputStreamReader(InputStream in, String encoding); Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (22) Zeichen-Klassen : Reader/ Writer (continued): Bei der Nutzung der konkreten Klasse findet eine Wandlung zwischen Bytes und Zeichen statt OutputStreamWriter (aus Writer abgeleitet): 25 Zeichen kommen von der Anwendung und werden als Bytes in einen OutputStream geschrieben Kodierungen wie für InputStreamReader Konstruktoren: 1. OutputStreamWriter(OutputStream out); 2. OutputStreamWriter(OutputStream out, String encoding); Kodierung lesen: String getEncoding(); Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ein-/ Ausgabe (23) Beispiel: import java.io.*; public class CopyCharacters{ public static void main(String[] args) throws IOException{ if(args.length != 2){ System.out.println("usage: java "+ "bs.CopyCharacters " + "<input file name> „ + "<output file name>"); return; } FileReader in = new FileReader(args[0]); FileWriter out = new FileWriter(args[1]); int c; int chars = 0; while((c = in.read()) != -1){ out.write(c); chars++; } in.close(); out.close(); } } 26 Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (1) Bis jetzt wurden auf Inhalte von Dateien zugegriffen Jetzt: 1) Bearbeiten der Attribute von Dateien Zugriff mit Java 2) 3) 27 Implementierung Manipulationen, die über das Lesen und Schreiben von Datei-Inhalten hinausgehen: • Datei umbenennen • Datei löschen • Inhalt eines Verzeichnisses auslesen Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (2) Konzept von Dateisystemen Permanenter („nicht-flüchtiger“) Speicher 1) • Speicher ist immer noch vorhanden nachdem ein Prozesse zu Ende gelaufen ist • Auch nach dem Herunterfahren eines Betriebssystems ist der Speicher immer noch vorhanden 2) Realisierung von Dateisystemen erfolgt durch Platte, Floppy, CD, Dateiserver 3) Keine rohe Nutzung der Hardware, sondern Konzept einer Datei (Datenstrom), identifiziert durch Name 4) Dateisysteme gruppieren Dateien zu Verzeichnissen 28 Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (3) Dateinamen In der Regel: Zeichenketten Für menschliche Benutzer geeignet In manchen Systemen werden Groß- und Kleinbuchstaben unterschieden (UNIX), in Anderen nicht (DOS) In manchen Systemen ist die Struktur des Dateinamens vorgegeben (max. 8 Zeichen, '.', max. 3 Zeichen in DOS), in Anderen nicht (Name besteht aus max. Anzahl von ASCII-Zeichen, u.a. '.', in UNIX) 29 Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (4) Verzeichnisse Aufgabe: Katalogisieren aller Dateien einer Festplatte oder einer Diskette etc… Ein Verzeichnis kann nicht nur Dateien, sondern auch andere Verzeichnisse enthalten Diese Struktur führt zu einem Dateibaum Verzeichnisse sind auch Dateien (in der Regel als Verzeichnisse besonders gekennzeichnet). Sie besitzen also auch Dateinamen 30 Verzeichnisse sind anhand von Pfaden zu ermitteln: Pfadnamen: z. B.: "/ich/mach/dummes/Zeug“ Datei oder Verzeichnis "Zeug" in Verzeichnis "dummes" in Verzeichnis "mach" in Verzeichnis "ich" in Wurzel- Verzeichnis Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (5) Verzeichnisse (continued) Ein Verzeichnis kann nicht nur Dateien, sondern auch andere Verzeichnisse enthalten Absolute Pfadnamen beginnen vom Wurzel-Verzeichnis Relative Pfadnamen beginnen vom aktuellen Verzeichnis: z.B. aktuelles Verzeichnis "/ich/mach" und relativer Pfadname "dummes/Zeug"; Spezialverzeichnisse 31 /: Wurzel .: dieses Verzeichnis ..:Vorgänger-Verzeichnis Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (6) Dateiattribut 32 Neben dem Inhalt und dem Namen gibt es weitere Attribute einer Datei (Dabei können Inhalt und Name auch zu den Attributen gezählt werden oder auch nicht): Größe Zeit des letzten Zugriffs, des letzten Schreibens Besitzer Zugriffsrechte Dateityp (reguläre Datei, Verzeichnis, ...) Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (7) Implementierung von Dateien Entscheidender Aspekt Abspeicherung von Dateien als zusammenhängenden Menge von Plattenblöcken (Methode 1) Zusammenhängende Belegung des Speicherplatzes hat zwei Vorteile: 1. 2. 1. 33 Zuordnung Datei Folge von Blöcken Bsp: Ein 50-KB-Datei würde folglich 50 aufeinanderfolgende Blöcke auf einer Platte mit 1 KB großen Blöcken, belegen Einfach zu implementieren, da Lokalisierung eines Dateiblocks nur anhand der Platenadresse des ersten Blocks und der Anzahl der Blöcke in einer Datei Sehr effizientes Lesen der kompletten Datei (höchste Performanz), da gesamte Datei mit einer einzigen Operation von der Platte gelesen werden kann Nachteil: Reservierung des maximalen Platzes bei Erzeugung führt früher oder später zu einer Fragmentierung der Platte Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (8) Implementierung von Dateien (continued) Entscheidender Aspekt Abspeicherung von Dateien als eine verkette Liste von Plattenblöcken (Methode 2) Vorteile: 1. 2. 34 jeder Block enthält Blocknr. des nächsten Blocks 1. Block und Länge kennzeichnet Inhalt einer Datei (wie bei zusammenhänge Belegung) Es geht kein Speicherplatz verloren durch Fragmentierung Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (9) Implementierung von Dateien (continued) 35 Entscheidender Aspekt Abspeicherung von Dateien als eine verkette Liste von Plattenblöcken in separatem Index (Im Hauptspeicher) (Methode 3) Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (10) Implementierung von Dateien (continued) Entscheidender Aspekt Abspeicherung von Dateien als eine verkette Liste von Plattenblöcken in separatem Index (Im Hauptspeicher) (Methode 3) Vorteile: Nachteil: 36 1. Block kennzeichnet weiterhin Inhalt einer Datei Einfacher wahlfreier Zugriff Gesamter Index die ganze Zeit im Hauptspeicher, bei größeren Dateisystemen kann dies mehrere MB groß sein Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (10) Implementierung von Dateien (continued) Entscheidender Aspekt Dateien folgen einer bestimmten Datenstruktur I-Node (Methode 4) 37 Nur die Listen der gerade geöffneten Dateien müssen im Hauptspeicher sein Aber: Für lange Dateien Lange Liste! Abhilfe: Indirekte Blöcke (d.h. Blöcke enthalten keine Daten, sondern weitere Liste von Blöcken UNIX: Liste von Blöcken in Inode (Index Node, Index-Knoten) zusammen mit Attributen Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (11) Implementierung von Dateien (continued) Entscheidender Aspekt Dateien folgen einer bestimmten Datenstruktur I-Node (Methode 4) Mischformen (UNIX): Blockliste Block 0 - 9: Daten Block 10: indirekter Block Block 11: zweifach indirekter Block Block 12: dreifach indirekter Block 38 Betriebssysteme Wintersemester 2015 © Patrick Kendzo Dateisystem (12) Bearbeiten von Dateien in Java Klasse File (Abgeleitet von Object) Repräsentiert einen Dateinamen, nicht unbedingt eine Datei Erlaubt den Zugriff auf Dateiattribute Konstruktoren: public File(String pathname); public File(String parent, String child); public File(File parent, String child); Konstante: separatorChar: Trennzeichen in einem Pfadnamen ('\' für Windows oder '/' für UNIX) 39 Methoden (siehe hierzu die Java Documentation) Betriebssysteme Wintersemester 2015 © Patrick Kendzo Ende 40 Betriebssysteme Wintersemester 2015 © Patrick Kendzo