Java InputOutput Reading standard input Surprisingly complicated GUI

  • Slides: 29
Download presentation
Java Input/Output

Java Input/Output

Reading standard input • Surprisingly complicated (GUI focus) • Old-fashioned way: Buffered. Reader r

Reading standard input • Surprisingly complicated (GUI focus) • Old-fashioned way: Buffered. Reader r = new Buffered. Reader(new Input. Stream. Reader(System. in)); String line = null; while ((line = r. read. Line()) != null) { // process line … }

Two modern ways Scanner s = new Scanner(System. in); while (s. has. Next. Line())

Two modern ways Scanner s = new Scanner(System. in); while (s. has. Next. Line()) { String line = s. next. Line(); // process line … } Console r = System. console(); String line = null; while ((line = r. read. Line()) != null) { // process line … }

Utility methods for Strings “the quick brown fox”. split(“ ”); => {“the”, “quick”, ”brown”,

Utility methods for Strings “the quick brown fox”. split(“ ”); => {“the”, “quick”, ”brown”, ”fox”} String. value. Of(13) => “ 13” String. value. Of(x) => x. to. String() Integer. parse. Int(“ 37”) => 37 (int) new Integer(“ 37”) => 37 (Integer object) similar for other primitives types …

Random. Access. File • makes files available “like a big array of bytes”, allows

Random. Access. File • makes files available “like a big array of bytes”, allows random read/write access anywhere inside a file • only supports primitive types + Strings • new Random. Access. File(String file. Name, String mode), where mode is “r”, ”rws”, ”rwd” • void seek(long pos) • long get. File. Pointer() • double read. Double() and similar • long length() • void set. Length(long new. Length)

Random. Access. File example Random. Access. File rf = new Random. Access. File(“doubles”, ”rw”);

Random. Access. File example Random. Access. File rf = new Random. Access. File(“doubles”, ”rw”); // read third double: go to 2 * 8 (size of one) rf. seek(8*2); double x = rf. read. Double(); // overwrite first double value rf. seek(0); rf. write. Double(x); rf. close();

Streams vs. Readers/Writers • Confusing number of alternatives: – Streams: for binary 8 bit

Streams vs. Readers/Writers • Confusing number of alternatives: – Streams: for binary 8 bit (byte) quantities – Readers/Writers: for String and 16 bit Unicode characters • Streams: always 8 bit quantities at the lowest level, but may provide higher-level abstractions as well, e. g. – read. Int() [in class Data. Input. Stream] will process four 8 bit values to read a single 32 bit int value

Input. Stream hierarchy Input. Stream Byte. Array File Filter Piped Object Sequence Input. Stream

Input. Stream hierarchy Input. Stream Byte. Array File Filter Piped Object Sequence Input. Stream Data Buffered Line. Number Push. Back Input. Stream Physical: Byte. Array. Input. Stream, File. Input. Stream, Piped. Input. Stream Virtual: all others

Class Input. Stream abstract class Input. Stream { int read() throws IOException; int read(byte[]

Class Input. Stream abstract class Input. Stream { int read() throws IOException; int read(byte[] buffer) throws IOException; long skip(long n) throws IOException; int available() throws IOException; void close() throws IOException; } • IOException: e. g. file cannot be opened, read operation was interrupted, …

Physical input streams • Some constructors: – Byte. Array. Input. Stream(byte[] buffer); – Byte.

Physical input streams • Some constructors: – Byte. Array. Input. Stream(byte[] buffer); – Byte. Array. Input. Stream(byte[] buffer, int offset, int count) – File. Input. Stream(File f); – File. Input. Stream(String file. Name); – Piped. Input. Stream(Piped. Output. Stream p); • Why use File instead of String as argument to the File. Input. Stream constructor?

Virtual input streams • Build on top of physical ones using composition, additional behaviour,

Virtual input streams • Build on top of physical ones using composition, additional behaviour, e. g. : – Sequence. Input. Stream: appends a couple of Input. Streams giving the impression/illusion of Client just a single stream – Filter. Input. Stream: an instance of the “Wrapper read() design pattern” Filter read() Input. Stream

Data. Input. Stream class Data. Input. Stream extends Filter. Input. Stream implements Data. Input

Data. Input. Stream class Data. Input. Stream extends Filter. Input. Stream implements Data. Input { … public boolean read. Boolean() throws IOException public byte read. Byte() throws IOException public char read. Char() throws IOException public double read. Double() throws IOException public int read. Int() throws IOException public long read. Long() throws IOException public short read. Short() throws IOException public int read. Unsigned. Byte() throws IOException public int read. Unsigned. Short() throws IOException } • • • Read bytes (binary representation, not textual), return them as primitive data types Possibly generated by Data. Output. Stream Same interface also used by Random. Access. File

Stream Tokenizer • Useful to break up text into tokens (words, numbers, others): public

Stream Tokenizer • Useful to break up text into tokens (words, numbers, others): public class Token. Test { public static void main(String[] args) { Stream. Tokenizer tok = new Stream. Tokenizer(System. in); try { while (tok. next. Token() != tok. TT_EOF) { switch(tok. ttype) { case tok. TT_NUMBER: System. out. println(“number “ + tok. val); break; … case default: … }} } catch (IOException e) {} }} • “ 23 -skidoo, kid!” yields: number 23. 0 token – word skidoo …

Output stream hierachy Output. Stream Byte. Array File Filter Piped Output. Stream Object Output.

Output stream hierachy Output. Stream Byte. Array File Filter Piped Output. Stream Object Output. Stream Data Buffered Print. Stream Output. Stream Similar to Input. Stream hierarchy: physical: Byte. Array. Output. Stream, File. Output. Stream, Piped. Output. Stream virtual: all others

Output. Stream public abstract class Output. Stream { public abstract void write(int b) throws

Output. Stream public abstract class Output. Stream { public abstract void write(int b) throws IOException public void write(byte[] buffer) throws IOException public void flush() throws IOException public void close() throws IOException } • Quite a few output streams use buffering (for efficiency reasons), flush() explicitly forces completion of pending output operations

Print. Stream public class Print. Stream extends Filter. Output. Stream { … public void

Print. Stream public class Print. Stream extends Filter. Output. Stream { … public void print(boolean bool) public void print(int inum) public void print(float fnum) public void print(double dnum) public void print(String str) public void print(Object o) { print(o. to. String()); } … } • Generates textual representations • print(Object o) is purely polymorphic

Object Serialization • Transform instances into 8 bit units can be send over networks,

Object Serialization • Transform instances into 8 bit units can be send over networks, stored in filesystems • Allows for object persistence, i. e. save state across program invocations • Interface Serializable, classes Object. Input. Stream and Object. Output. Stream • Would be tricky: need to get shared structure right!

Object Serialization example import java. io. Serializable; class Pair implements Serializable { public Object

Object Serialization example import java. io. Serializable; class Pair implements Serializable { public Object first; public Object second; } class Holder implements Serializable { public Object value; } • Actually empty interface, so “implements Serializable” suffices

Object Serialization example contd. import java. util. Date; … Date today = new Date();

Object Serialization example contd. import java. util. Date; … Date today = new Date(); Holder a = new Holder(); a. value = today; Holder b = new Holder(); b. value = today; Pair c = new Pair(); c. first = a; c. second = b; c a b today

Object Serialization: write to file try { File. Output. Stream f = new File.

Object Serialization: write to file try { File. Output. Stream f = new File. Output. Stream(“save. State”); Object. Output. Stream s = new Object. Output. Stream(f); s. write. Object(“The value of c is”); s. write. Object(c); s. flush(); } catch (IOException e) System. out. println(“received error “ + e); }

Object Serialization: read back try { File. Input. Stream f = new File. Input.

Object Serialization: read back try { File. Input. Stream f = new File. Input. Stream(“save. State”); Object. Input. Stream s = new Object. Input. Stream(f); String tag = (String) s. read. Object(); Pair c = (Pair) s. read. Object(); } catch (IOException e) { System. out. println(“received IO exception “ + e); } catch (Class. Not. Found. Exception e) { System. out. println(“received class exception “ + e); }

Object Serialization: check == … Holder a = (Holder) c. first; Holder b =

Object Serialization: check == … Holder a = (Holder) c. first; Holder b = (Holder) c. second; if( a. value == b. value ) System. out. println(“it’s the same object”); …

Piped IO • Producer/consumer paradigm • Multiple threads and pipes • A pipe: buffered

Piped IO • Producer/consumer paradigm • Multiple threads and pipes • A pipe: buffered data area used for both reading and writing • May suspend on IO operations: – Read, because empty – Write, because full • In Java: matched pair of streams: Piped. Input. Stream in = new Piped. Input. Stream(); Piped. Output. Stream out = new Piped. Output. Stream(in);

Piped IO Example: Fibonacci + Prime class Fib. Maker extends Thread { private Data.

Piped IO Example: Fibonacci + Prime class Fib. Maker extends Thread { private Data. Output. Stream out; public Fib. Maker(Data. Output. Stream o) {out = o; } public void run() { int n = 0; int m = 1; try { out. write. Int(m); while(m<100000) { int new. Value = n+m; n=m; m=new. Value; out. write. Int(new. Value); } out. close(); } catch (IOException e) {return; }}}

Piped IO Example contd. class Pipe. Test { static public void main(String[] args) {Pipe.

Piped IO Example contd. class Pipe. Test { static public void main(String[] args) {Pipe. Test w = new Pipe. Test(); w. show(System. out); } private Pipe. Test(Print. Stream out) { Data. Input. Stream fibs = make. Fibs(); Data. Input. Stream primes = make. Primes(); try { int x = fibs. read. Int(); int y = primes. read. Int(); while (x < 100000) { if (x == y) { out. println(x + “ is both prime and fib”); x = fibs. read. Int(); y = primes. read. Int(); } else if (x<y) x = fibs. read. Int(); else y = primes. read. Int(); } } catch (IOException e) { System. exit(0); }}

Piped IO Example contd. private Data. Input. Stream make. Fibs() { try { Piped.

Piped IO Example contd. private Data. Input. Stream make. Fibs() { try { Piped. Input. Stream in = new Piped. Input. Stream(); Piped. Output. Stream out = new Piped. Output. Stream(in); Thread fib. Thread = new Fib. Maker (new Data. Output. Stream(out)); fib. Thread. start(); return new Data. Input. Stream(in); } catch (IOException e) { return null; } }

Readers and Writers hierarchy Reader Buffered Reader Char. Array Reader Line. Number Reader Input.

Readers and Writers hierarchy Reader Buffered Reader Char. Array Reader Line. Number Reader Input. Stream Reader Filter Reader File Reader Pushback Reader Piped Reader Writer Buffered Writer Char. Array Output. Stream Filter Piped Writer File. Writer Print String Writer String Reader

Readers/Writers • Purely textual, but similar to IO streams try { File. Reader f

Readers/Writers • Purely textual, but similar to IO streams try { File. Reader f = new File. Reader(“filename”); Buffered. Reader b = new Buffered. Reader(b); … } catch (…){ … } … • Also wrap around IO streams: File. Input. Stream f = new File. Input. Stream(“f”); Input. Stream. Reader r = new Input. Stream. Reader(f, “Mac. Cyrillic”); Buffered. Reader b = new Buffered. Reader(r); String text = r. read. Line();

String. split(String Regex) • even simpler than Stream. Tokenizer "boo: and: foo”. split(“: ”)

String. split(String Regex) • even simpler than Stream. Tokenizer "boo: and: foo”. split(“: ”) -> {“boo”, ”and”, ”foo”} "boo: and: foo”. split(“o”) -> {“b”, ”: and: f”} • Typical loop to process file input: Buffered. Reader reader = new Buffered. Reader( new File. Reader(file. Name)); String line = null; while ((line = reader. read. Line()) != null) { String[] tokens = line. split(“ “); // process tokens … }