Programmieren I. Dateien: Allgemeines. Vorlesung 10. Handout S. 1. Martin Schultheiß. Hochschule Darmstadt Wintersemester 2010/2011

Ähnliche Dokumente
Dateien: Allgemeines Dateien lesen Beispiel: CSV-Daten Filter Ausgabe in Dateien. Programmieren I. Martin Schultheiß

Dateien: Allgemeines Dateien lesen Beispiel: CSV-Daten Filter Ausgabe in Dateien. Programmieren I. Dr. Klaus Höppner

java.io Ziel Ressourcen Page 1 Verstehen der unterschiedlichen I / O Möglichkeiten Anwenden der Java I/ O Klassen Java Tutorial Java API Dokumentation

Handbuch konsultieren!

Javakurs für Fortgeschrittene

Eingabe und Ausgabe in Java. Dr. Horst Treiblmaier Abteilung für Wirtschaftsinformatik WU Wien

Ausnahmen. Gilbert Beyer und Annabelle Klarl. Einführung in die Informatik. Zentralübung zur Vorlesung Einführung in die Informatik

Ausnahmen. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Software Entwicklung 1

Ausnahmen. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Info B VL 7: Input/Output

Analyse und Modellierung von Informationssystemen

Einstieg in die Informatik mit Java

Streams. V by WBR1&MOU2/BFH-TI. Berner Fachhochschule Hochschule für Technik und Informatik HTI

Java I/O. Input / Output stream Library Regelt I/O über verschiedene Kanäle. Führt notwendige Umwandlungen/Konvertierungen aus

Abschnitt 18: Beispiel: I/O-Streams

Streams. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java

Ausnahmen. Dr. Philipp Wendler. Zentralübung zur Vorlesung Einführung in die Informatik: Programmierung und Softwareentwicklung

Arten von Streams. Daten. Bytes (8-Bits) Java Programm. Daten. Java Programm. Characters (16 - Bits)

Kapitel 12. Programmierkurs. Allgemeine Konzepte Byte-Streams versus Character-Streams

Java Fehlerbehandlung

Ausnahmen. Dr. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Ausnahmen. Philipp Wendler. Zentralübung zur Vorlesung Einführung in die Informatik: Programmierung und Softwareentwicklung

Datenströme in Java. Zeichenkonvertierung

Vorlesung Programmieren

Java Einführung Exception Handling. Kapitel 17

Programmieren in Java

Vorlesung Programmieren. Java I/O: Input und Output mit Java. Ein-/Ausgabe von Daten. Java I/O. Heute. Grundlage fast aller Programme

Ein- und Ausgabe in Java

Grundlagen der Programmierung! Kapitel 10: Ein- und Ausgabe! Ziele dieses Kapitels! Datei! Das Problem!

Programmieren 2 Selbststudium Semesterwoche 6

Java I Vorlesung Exceptions

JAVA für Einsteiger. Streams und Dateien. eden market Autor: Norman Lahme

high level I/O/ low level I/O

Modellierung und Programmierung 1

Ausdrucksbäume in verschiedenen Darstellungen

Ausnahmen und IO. Fehler, Ausnahmen, Java- Exception, throw, catch, Ströme, Puffer, Dateien lesen, schreiben, Tastatur, Terminal, HTTP

Client-Server TCP/IP - Kodierung

Programmieren 2 09 File-IO

Java I/O. Input / Output stream Library Regelt I/O über verschiedene Kanäle. Führt notwendige Umwandlungen/Konvertierungen aus

1 Klassen anlegen und Objekte erzeugen

Einführung in die OOP mit Java Character-Streams Gliederung

1 Klassen anlegen und Objekte erzeugen

Java Einführung IO (Eingabe/Ausgabe)

Grundlagen der Programmierung. Kapitel 10: Ein- und Ausgabe. Ziele dieses Kapitels. Das Problem. Datei

Grundlagen der Programmierung. Kapitel 11: Ein- und Ausgabe. Ziele dieses Kapitels. Das Problem. Datei

Grundlagen der Programmierung. Kapitel 11: Ein- und Ausgabe. Ziele dieses Kapitels. Das Problem. Datei

AK-Automatisierungs und Kommunikationstechnik TI Technische Informatik. NWT Netzwerktechnik

Java Übung. Übung 3. Werner Gaulke. 2. Mai Universität Duisburg-Essen Kommedia, Übung EinPro SS06, Einführung in Java - Übung.

Wie schreibt bzw. wie liest man die beiden unterschiedlichen Darstellungen?

Einfache Liste: Ein Stapel (Stack) Ansatz. Schaubild. Vorlesung 1. Handout S. 2. Die einfachste Form einer Liste ist ein Stapel (stack).

Polymorphie/Späte Bindung Abstrakte Klassen Interfaces. Polymorphie/Späte Bindung Abstrakte Klassen Interfaces

Verteilte Systeme - Java Networking (Sockets) 2 -

Objektorientierung II & die Java Klassenbibliothek. Kristian Bergmann und Arthur Lochstampfer

Streams. Thomas Schwotzer

Ausnahmebehandlung PK11W-16,

Institut für Programmierung und Reaktive Systeme 10. Mai Programmieren II. 11. Übungsblatt

Programmieren I. Kapitel 15. Ein und Ausgabe

! 1. Unterklassen und Vererbung! 2. Abstrakte Klassen und Interfaces! 3. Modularität und Pakete! 4. Ausnahmen (Exceptions) II.4.

Grundlagen der Programmierung! Kapitel 10: Ein- und Ausgabe! Ziele dieses Kapitels! Das Problem! Datei!

Client-Server TCP/IP - Kodierung

Institut für Programmierung und Reaktive Systeme 7. Mai Programmieren II. 11. Übungsblatt

Grundlagen der Objektorientierten Programmierung - Ein- / Ausgabe-Streams

Javakurs für Fortgeschrittene

Kapitel 15: Ausnahmen und

Beispiel: Temperaturumwandlung. Imperative Programmierung. Schwerpunkte. 3. Grundlegende Sprachkonstruktionen imperativer Programme

Versuchsziele Konzepte der parallelen Programmierung am Beispiel von Threads anwenden können. Einbau von Kontrollmechanismen mittels Semaphore.

Modellierung und Programmierung 1

Software Entwicklung 1

Socket-Programmierung unter Java

Dateien, Streams. INE2 M. Thaler, Office TG ZHAW, M. Thaler, K. Rege, G. Burkert, E.

Programmieren 2 09 File-IO

Socket-Programmierung unter Java

8. Arbeiten mit Dateien

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 23

Verteilte Systeme - Java Networking (Sockets) -

Algorithmen und Programmierung III

3.11 Ausnahmen und Ein-/Ausgabe

Programmiertechnik Ausnahmen

Ein-/Ausgabe, Dateisystem. Kapitel 9: Ein-/Ausgabe. Programmieren in C für Elektrotechniker. Programmieren in C. Dateisystem. Programmieren in C

Ein- und Ausgabe. Algorithmen und Datenstrukturen II 1

Umleitung von Datenströmen

Distributed Computing Group

Grundlagen von JAVA Hello World in JAVA Elementare Datentypen. Grundlagen von JAVA Hello World in JAVA Elementare Datentypen

Autoboxing - Nachtrag

Vorlesung Programmieren

Prof. Dr. Oliver Haase Karl Martin Kern Achim Bitzer. Programmiertechnik Ausnahmen

Dateizugriff unter C

Übung Informatik I - Programmierung - Blatt 6

hue13 January 30, 2017

boolean ispalindrome = word.equalsignorecase(reverse.tostring());

3. Grundlegende Sprachkonstruktionen imperativer Programme

Dr. Monika Meiler. Inhalt

Transkript:

Programmieren I Martin Schultheiß Hochschule Darmstadt Wintersemester 2010/2011 1 / 26 Dateien: Allgemeines Dateien lesen Beispiel: CSV-Daten Filter Ausgabe in Dateien 2 / 26 Dateien: Allgemeines Kaum eine Anwendung im echten Leben kommt ohne Dateien aus, sei es zum Lesen oder Schreiben (oder beides). Hierbei wird im Wesentlichen zwischen zwei Typen von Dateien unterschieden: Textdateien enthalten lesbaren Text. Diese kann man in einem normalen Editor (notepad, emacs,... ) öffnen, lesen und bearbeiten. Binärdateien enthalten Daten in binärer Form, die nicht zum direkten Lesen durch den Menschen gedacht sind (und zum Teil auch nicht druckbare Zeichen enthalten), sondern zur Verarbeitung durch ein Programm gedacht sind. Beispiele hierfür sind Word-, Excel-Dateien, Grafiken (z. B. GIF, JPG), Musik (z. B. MP3). 3 / 26 Handout S. 1

Was ist eine Datei? In erster Linie ist eine Datei eine Menge von Bytes bzw. Zeichen auf einem Speichermedium, in die man Bytes bzw. Zeichen sequenziell schreiben oder daraus lesen kann. Zweitens sind mit einer Datei (je nach Fähigkeiten des Betriebssystems) Eigenschaften wie Dateiname, Zugriffsrechte (teilweise je nach User unterschiedlich) oder Zugriffs-, Modifikationsdatum verbunden. In dieser Vorlesung geht es um den ersten Punkt, also das Schreiben und Lesen von Daten. 4 / 26 Eingabeströme Java stellt zwei einfache, abstrakte Klassen für Eingabeströme zur Verfügung: InputStream stellt rudimentäre Funktionalität zum Lesen von Bytes zur Verfügung. Reader stellt rudimentäre Funktionalität zum Lesen von Zeichen zur Verfügung. (NB: Dass Lesen von Bytes und Zeichen ein Unterschied ist, liegt daran, dass es in Zeiten von Unicode Zeichen aus mehr als einem Byte bestehen können multi byte characters) Diese Sicht auf einen Datenstrom zur Eingabe ist allgemein und nicht nur auf Dateien bezogen. Genauso könnte sich also ein InputStream auf einen String oder eine Socket-Verbindung im Netzwerk beziehen. 5 / 26 Methoden von Reader close() Schließen der Datei, implementiert die abstrakte Methode aus dem Interface Closeable. read(char cbuf[], int offset, int length) liest in einen Character-Array cbuf ab dem Offset oset eine Menge von length Zeichen. Das Lesen ist blockierend, d. h., wenn weniger Zeichen im Eingabestrom zur Verfügung stehen, wird gewartet (es sei denn, es tritt EOF end of file auf). Rückgabewert: Zahl der gelesenen Zeichen, oder 1 nach EOF Diese Methode ist abstrakt und muss in eigenen Reader-Klassen implementiert werden! read(char cbuf[]) Äquivalent zu read(cbuf,0, cbuf.length). read() liest ein Zeichen ein, wobei dieses als int zurückgegeben wird, bzw. 1, falls das Dateiende erreicht wurde. 6 / 26 Handout S. 2

Weitere Readerklassen Die Klasse Reader als abstrakte Klasse stellt die allgemeine Grundfunktionalität zur Verfügung. Konkrete Implementierungen von Reader sind z. B.: InputStreamReader Dieser Reader macht aus einem Byte-Stream InputStream, der dem Konstruktor übergeben wird, einen Character-Stream. Beispiel: new InputStreamReader(System.in) FileReader Dieser Reader liest aus einer Datei auf einem Speichermedium (z. B. Festplatte): new FileReader("daten.txt") 7 / 26 Weitere Readerklassen (Forts.) Im Prinzip reicht die Klasse FileReader völlig aus, um aus einer Datei lesen zu können... es ist nur sehr unbequem, dies zeichenweise tun zu müssen. Beim Lesen von Text-Dateien will man meist zeilenweise lesen. Dies kann mit mit der Klasse BueredReader geleistet werden. BueredReader ist ein High-Level-Reader, der einen anderen Reader um die Möglichkeit bereichern kann, eine Zeile als String einzulesen. Hierfür dient dann die Methode String readline(). 8 / 26 Beispiel: Eingabe von der Tastatur import java. i o. * ; p u b l i c c l a s s App { p u b l i c s t a t i c void main ( S t r i n g [ ] args ) { BufferedReader i n = new BufferedReader ( new InputStreamReader ( System. in ) ) ; try { S t r i n g z e i l e = in. readline ( ) ; catch ( IOException e ) { e. printstacktrace ( ) ; 9 / 26 Handout S. 3

Analyse Am vorigen Beispiel wird das Konzept der Stream- und Reader-Klassen in Java mit einer Trennung in Low-Level- und High-Level-Klassen deutlich: System.in ist ein allgemeiner InputStream, aus dem Bytes gelesen werden können, InputStreamReader macht aus diesem Stream einen Low-Level-Reader, aus dem eine Menge von Zeichen gelesen werden kann, BueredReader dekoriert diesen Low-Level-Reader mit einem High-Level-Reader, der dann zeilenweises Einlesen erlaubt. Hierdurch wird eine Trennung zwischen Datenquelle und der Art des Lesens erreicht. Die Physik (Lesen von der Platte, von einem Socket,... ) steckt im Low-Level-Reader, der Komfort dann im High-Level-Reader. 10 / 26 Beispiel: Eingabe aus einer Datei Das Lesen aus einer Datei ist nun fast identisch (außer, dass man die FileNotFoundException abfangen muss): import java. i o. * ; p u b l i c c l a s s App { p u b l i c s t a t i c void main ( S t r i n g [ ] args ) { BufferedReader i n ; try { i n = new BufferedReader ( new FileReader ( " daten. txt " ) ) ; S t r i n g z e i l e = in. readline ( ) ; System. out. p r i n t l n ( z e i l e ) ; catch ( FileNotFoundException e ) { e. printstacktrace ( ) ; catch ( IOException e ) { e. printstacktrace ( ) ; 11 / 26 Beispiel: Lesen von CSV-Daten Für ein komplexeres Beispiel zum Lesen aus Dateien betrachten wir eine Klasse Adresse, die als Attribute Vor- und Nachname, Straße, PLZ und Ort besitzt: p u b l i c c l a s s Adresse { p r i v a t e S t r i n g vorname ; p r i v a t e S t r i n g nachname ; p r i v a t e S t r i n g s t r a s s e ; p r i v a t e S t r i n g p l z ; p r i v a t e S t r i n g o r t ; p u b l i c Adresse ( S t r i n g vorname, S t r i n g nachname, S t r i n g s t r a s s e, S t r i n g plz, S t r i n g o r t ) { t h i s. vorname = vorname ; t h i s. nachname = nachname ; t h i s. s t r a s s e = s t r a s s e ; t h i s. p l z = p l z ; t h i s. o r t = o r t ; 12 / 26 Handout S. 4

Beispiel: Lesen von CSV-Daten (Forts.) p u b l i c S t r i n g getnachname ( ) { return nachname ; p u b l i c S t r i n g getort ( ) { return o r t ; p u b l i c S t r i n g getplz ( ) { return p l z ; p u b l i c S t r i n g g e t S t r a s s e ( ) { return s t r a s s e ; p u b l i c S t r i n g getvorname ( ) { return vorname ; 13 / 26 Problemstellung Tabellen-artige Daten wie Adressen werden häufig in Form von comma separated values (CSV) in Text-Dateien gespeichert. Die können dann z. B. einfach von einer Tabellenkalkulation wie Excel verarbeitet werden. Beispiel für eine CSV-Datei: Karl;Mueller;Rosenstr. 7;12345;Rosendorf Erich;Mustermann;Musterweg 1;90000;Bad Homburg Angelika;Schmidt;Annastr. 23;22457;Hamburg Thomas;von Sokolowski;Rheinstr. 5;64283;Darmstadt Typisch ist, dass die Felder durch ein Zeichen separiert werden, das im Feldinhalt typischer Weise nicht vorkommt (z. B ; oder ). 14 / 26 Problemstellung (Forts.) Zum Einlesen von Adressdaten im CSV-Format soll der Klasse Adresse nun eine neue statische Methode Adresse[] parse(string dateiname) hinzu gefügt werden. Diese Methode muss also: eine Datei zum Lesen öffnen und mit einem BueredReader dekorieren, jede Zeile der Datei in einzelne Felder aufsplitten, den Konstruktor von Adresse mit diesen Daten aufrufen, die Adressen in einen Array packen und zurück geben. 15 / 26 Handout S. 5

Implementierung von parse p u b l i c s t a t i c Adresse [ ] parse ( S t r i n g dateiname ) { ArrayList <Adresse> temp = new ArrayList <Adresse >(); try { BufferedReader i n = new BufferedReader ( new FileReader ( dateiname ) ) ; S t r i n g z e i l e ; while ( ( z e i l e=in. readline ( ) )!= n u l l ) { S t r i n g [ ] items = z e i l e. s p l i t ( " ; " ) ; temp. add (new Adresse ( items [ 0 ], items [ 1 ], items [ 2 ], items [ 3 ], items [ 4 ] ) ) ; catch ( FileNotFoundException e ) { System. e r r. p r i n t l n ( "Kann Datei "+dateiname+" n i c h t ö f f n e n " ) ; catch ( IOException e ) { System. e r r. p r i n t l n ( " L e s e f e h l e r " ) ; System. out. p r i n t l n ( temp. s i z e ()+" Adressen e i n g e l e s e n " ) ; return temp. toarray (new Adresse [ 0 ] ) ; 16 / 26 Zwischenfilter Ein weiterer Vorteil des Konzepts mit Low-Level-Streams und diese dekorierenden High-Level-Streams liegt darin, dass man nach Wunsch Zwischen-Filter einbauen kann. Diese können transparent Ein- und Ausgabeströme manipulieren. Beispielsweise könnte man so erreichen, dass Daten beim Schreiben verschlüsselt und beim Lesen entschlüsselt werden, ohne dass die Anwendung dies merkt, weil dieser Prozess als Filter zwischen Low- und High-Level-Stream bzw. -Reader geschaltet ist. 17 / 26 Implementierung eines Filters Als kleines Beispiel soll ein Inputfilter implementiert werden, der alle eingelesenen Zeichen in Großbuchstaben umwandelt. Hierfür wird: eine neue Kindklasse von Reader definiert, diese dekoriert einen anderen Reader, der dem Konstruktor als Referenz übergeben wird, die abstrakten Methoden read(char [], int, int) und close () aus Reader implementiert, wobei die Implementierung jeweils auf die entsprechenden Methoden aus dem dekorierten Reader zurück greift, aber beim read (...) die eingelesenen Zeichen manipulieren kann. 18 / 26 Handout S. 6

Beispiel p u b l i c c l a s s UpperInputReader extends Reader { p r i v a t e Reader in ; p u b l i c UpperInputReader ( Reader in ) { t h i s. in = in ; @Override p u b l i c i n t read ( char [ ] cbuf, i n t o f f s e t, i n t length ) throws IOException { i n t count = super. read ( cbuf, o f f s e t, length ) ; f o r ( i n t i=o f f s e t ; i<o f f s e t+count ; i++) { cbuf [ i ] = Character. touppercase ( cbuf [ i ] ) ; return count ; @Override p u b l i c void c l o s e ( ) throws IOException { super. c l o s e ( ) ; 19 / 26 Anwendung Mit diesem Filter kann man nun einfach benutzen, um ganz transparent alle von der Tastatur gelesenen Zeichen als Großbuchstaben zu lesen: p u b l i c c l a s s App { p u b l i c s t a t i c void main ( S t r i n g [ ] args ) throws IOException { BufferedReader i n = new BufferedReader ( new UpperInputReader ( new InputStreamReader ( System. in ) ) ) ; S t r i n g z e i l e = in. readline ( ) ; System. out. p r i n t l n ( z e i l e ) ; Die Klasse FilterReader 20 / 26 Zur Vereinfachung des Schreibens von Filtern gibt es die Klasse FilterReader, die einen dem Konstruktor als Referenz übergebenen Reader dekoriert. Hierbei sind alle Methoden von Reader so implementiert, dass sie für den dekorierten Reader ausgeführt werden. Diese Klasse FilterReader ist dazu gedacht, dass eigene Filterklassen von dieser erben und dort einzelne Methoden überladen, um eine Manipulation des Eingabestroms zu erreichen. 21 / 26 Handout S. 7

Neue Version von UpperInputReader p u b l i c c l a s s UpperInputReader extends F i l t e r R e a d e r { p u b l i c UpperInputReader ( Reader in ) { super ( in ) ; @Override p u b l i c i n t read ( char [ ] cbuf, i n t o f f s e t, i n t length ) throws IOException { i n t count = super. read ( cbuf, o f f s e t, length ) ; f o r ( i n t i=o f f s e t ; i<o f f s e t+count ; i++) { cbuf [ i ] = Character. touppercase ( cbuf [ i ] ) ; return count ; 22 / 26 Ausgabe in Dateien Allgemeines Das Konzept der Ausgabe in Java ist analog zur Eingabe: Es gibt abstrakte Klassen OutputStream und Writer mit der Grundfunktionalität zum Schreiben von Bytes bzw. Zeichen. Low-Level-Klassen sorgen dafür, dass die abstrakten Methoden implementiert werden. Bei Dateien sind dies FileOutputStream und FileWriter, High-Level-Klassen erweitern die Grundfunktionalität, OutputStreamWriter dient als Brücke, um aus einem Byte-Ausgabestrom einen Character-Ausgabestrom in Form eines Writers zu machen. 23 / 26 Schaubild: Reader- und Writer-Klassen (aus: Friedrich Esser, Java 2 Designmuster und Zertifizierungswissen, Galileo Computing) 24 / 26 Handout S. 8

BueredWriter und PrintWriter Im Allgemeinen wird man einen Writer mit einer der Klassen BueredWriter oder PrintWriter dekorieren. Diese bieten insbesondere die Möglichkeit, mit der Methode println (...) zeilenweise Daten auszugeben. PrintWriter ermöglicht zusätzlich mit der Methode format (...) eine formatierte Ausgabe. 25 / 26 import java. i o. * ; import java. math. * ; Beispiel p u b l i c c l a s s App { p u b l i c s t a t i c void main ( S t r i n g [ ] args ) { try { PrintWriter out = new PrintWriter ( new F i l e W r i t e r ( " daten. txt " ) ) ; f o r ( double x=0; x<1; x+=.01) { out. format ( "%8.2 f %8.2 f \n", x, Math. s i n ( x ) ) ; out. c l o s e ( ) ; catch ( IOException e ) { e. printstacktrace ( ) ; 26 / 26 Handout S. 9