Files and Streams Dr. Jürgen Eckerle Files and Streams • System input and output through data streams, serialization and the file system is provided by the package java.io. • It must be imported by import java.io.*; • Streams represent an abstract input or output device. • There are super classes InputStream and OutputStream, Reader and Writer. • Concrete subclasses link the access routines to real input or output devices like files, strings or communication channels. 1 Files and Streams • Streams can be concatenated and nested. • Nested streams allow to realize filters with extended functionalities. • There are two categories of stream classes: – Byte streams (based on 8 Bit units) – Character streams (based on 16 Bit Unicode characters and realized with JDK 1.1). Files and Streams • Java uses the 16 Bit Unicode for internal representation of characters, and • the 8 Bit characters for external communication with files. • There are a set of bridge classes converts Character streams into Byte streams and vice versa. 2 Character Streams The abstract class Writer contains the following methods: protected Writer() public void close() public void flush() public void write(int c) public void write(char[] cbuf) abstract public void write(char[] cbuf, int off, int len) public void write(String str) public void write(String str, int off, int len) Character Streams • The constructor Writer() allows to open the output stream and to prepare it for the following write(...) commands. • close() closes the output stream. • The write(..) command is overloaded and is used to write the given input value to the output stream. • The write(int) command allows to write an int value as a byte to the output stream. All the other write(...) commands are based on it. • flush() forces to write characters possibly currently stored in a buffer to the output device. 3 Character Streams There are a set of concrete subclasses of the abstract class Writer, for example: • OutputStreamWriter a superclass for all Writer classes which convert a character stream into a byte stream. • FileWriter allows to print the output into a file. • FilterWriter • PrintWriter • BufferedWriter Character Streams BufferedWriter • is used to store the characters sent to the output stream in an internal buffer. • The internal stored characters are written to the buffer (file) if either – the buffer is full, or – the flush() command has been explicitely called. • Useful if the output is written into a file, since the number of external accesses will be reduced. 4 Character Streams PrintWriter • allows to print both as the primitive types as the objects in text form. FilterWriter • an abstract superclass which is used to implement self-defined Filter classes as a subclass of it. BufferedWriter, PrintWriter and FilterWriter can be used to realize nested streams. Exercise 1 • Write a small programm to write the string “Hallo Java“ into a text file. End of line character is “\r\n“. 5 Character Streams Nested streams. • BufferedWriter, PrintWriter and FilterWriter can be used to realize nested streams. • For that reason, these classes have a member variable of type Writer which is initialized with the constructor. • For example in the class BufferedWriter: – public BufferedWriter(Writer out) – public BufferedWriter(Writer out, int size) Character Streams Nested streams. • Calling the write method means that – first, apply the filter functions realized in the own class and – then, apply the write(...) method of the superclass. 6 Character Streams – Examples Writer f1; BufferedWriter f2; String s; try { f1 = new FileWriter("buffer.txt"); f2 = new BufferedWriter(f1); for (int i = 1; i <= 10000; ++i) { s = "Dies ist die " + i + ". Zeile"; f2.write(s); f2.newLine(); } f2.close(); f1.close(); } catch (IOException e) { System.out.println("Fehler beim Erstellen der Datei"); } PrintWriter f; double sum = 0.0; int nenner; try { f = new PrintWriter( new BufferedWriter( new FileWriter("zwei.txt"))); for (nenner = 1; nenner <= 1024; nenner *= 2) { sum += 1.0 / nenner; f.print("Summand: 1/"); f.print(nenner); f.print(" Summe: "); f.println(sum); } f.close(); } catch (IOException e) { System.out.println("Fehler beim Erstellen der Datei"); } 7 Exercise 2 • Write a small programm to write a sequence of values of type int into a text file. Exercise 3 • UpCaseWriter.java print a text in uppercase into text file. Study the listing of it. Explain why it works. 8 import java.io.*; class UpCaseWriter extends FilterWriter { public UpCaseWriter(Writer out) { super(out); } public void write(int c) throws IOException { super.write(Character.toUpperCase((char)c)); } public void write(char[] cbuf, int off, int len) throws IOException { for (int i = 0; i < len; ++i) { write(cbuf[off + i]); } } public void write(String str, int off, int len) throws IOException { write(str.toCharArray(), off, len); } } public class Exercise3 { public static void main(String[] args) { PrintWriter f; String s = "und dieser String auch"; try { f = new PrintWriter( new UpCaseWriter( new FileWriter("upcase.txt"))); //Aufruf von außen f.println("Diese Zeile wird schön groß geschrieben"); //Test von write(int) f.write('a'); f.println(); //Test von write(String) f.write(s); f.println(); //Test von write(String, int, int) f.write(s,0,17); f.println(); //Test von write(char[], int, int) f.write(s.toCharArray(),0,10); f.println(); //--f.close(); } catch (IOException e) { System.out.println("Fehler beim Erstellen der Datei"); } } } 9 Character Streams The abstract class Reader contains the following methods: public Reader() public void close() public void mark(int readAheadlimit) public boolean markSupported() public int read() public int read(char[] cbuf) public int read(char[] cbuf, int off, int len) public long skip(long n) public boolean ready() public void reset() Character Streams • The constructor Reader() allows to open the input stream and to prepare it for the following read(...) commands. • close() closes the input stream. • The read(...) method is overloaded and is used to read a character from a given input stream. • The read() method reads the next character and returns as an int value in the range [0, 65535]. A return value -1 indicates that the end of the input stream is reached. 10 Character Streams • The read(char[ ], int, int) method reads a set of characters and fill the given input array char. The return value yield the number of input values readed from the input stream. A return value -1 indicates that the end of the input stream is reached. • The method boolean ready() returns the value true, if the next character can be read without being blocked. Character Streams • The method markSupported() checks whether marking a position is supported. • If marking is supported a given position can be marked by calling the method mark(int). The input value readAheadLine specifies the number of characters which can be read until the mark is invalid. • If a position is marked, the position index is set to the marked position by calling reset(). • The method skip(int) allows to skip a given number of input value. If it is not possible to skip the specified number of characters, the return values yields the actual number. 11 Character Streams Subclasses of the abstract class Reader: • InputStreamReader a superclass of all Reader classes which converts a byte stream into a character stream. • FileReader allows to read the input stream from a file. • FilterReader: An abstract class for self-defining a Flterclass. • BufferedReader • PushbackReader Character Streams • StringReader and CharArrayReader allows to read from a string object resp. a char array. Reader f; int c; String s; s = "Das folgende Programm zeigt die Verwendung\r\n"; try { f = new StringReader(s); while ((c = f.read()) != -1) { System.out.print((char)c); } f.close(); } catch (IOException e) { System.out.println("Fehler beim Lesen des Strings"); } 12 Exercise 4 • Write a program which corresponds with the Exercise 1, that is, a program which reads a string from a text file and print it with the method System.out.print() on the command line. • Write a program which corresponds with Exercise 2, that is, a program which reads read a sequence of integers and print them with the method System.out.println(). Character Streams Nested Readers. • The Reader classes – – – – BufferedReader, LineNumberReader, FilterReader, and PushbackReader • can be used, since they have a member variable Reader which is initialized by the constructor. • In contrast to the Writer reading means – first, apply the read method from the inner Reader, – then, apply the read method of the Filter Reader. 13 Character Streams • LineNumberReader extends the functionality of the BufferedReader by ability to count the number of input lines during the read process. There are two additional methods – int getLineNumber() – void setLineNumber(int) • FilterReader is used as a superclass which a selfdefined FilterReader class has to extend. • PushbackReader allows to give a character back to the input stream (by unread(...)) after a call of the read() method. This class is used, if the next character must be known to make the right decision, without processing it. 14