860 likes | 874 Views
I/O. I/O: sequential and random access streams sequential uniform specification for any data transfer file I/O network transmission to/from memory InputStream OutputStream. Input streams. InputStream. File Input Stream. Filter Input Stream. Piped Input Stream. Object Input Stream.
E N D
I/O I/O: sequential and random access • streams • sequential • uniform specification for any data transfer • file I/O • network transmission • to/from memory • InputStream • OutputStream
Input streams InputStream File Input Stream Filter Input Stream Piped Input Stream Object Input Stream Sequence Input Stream ByteArray Input Stream Data Input Stream Buffered Input Stream Pushback Input Stream LineNumber Input Stream
Input streams (cont.) abstract class InputStream { //read a singe byte from the input int read() throws IOException; //read an array of values from the input int read(byte[] buffer) throws IOException; //skip the indicated number of values from input long skip(long n) throws IOException; //determine number of bytes readable without blocking int available() throws IOException; //close this input stream void close() throws IOException; }
Input streams (cont.) • Physical input stream • ByteArrayInputStream • FileInputStream • PipedInputStream ByteArrayInputStream(byte[] buffer); ByteArrayInputStrean(byte[] buffer, int offset, int count); FileInputStream(File f); FileInputStream(String fileName); PipedInputStream(PipedOutputStream p);
Input streams (cont.) • Virtual input streams • SequenceInputStream • ObjectInputStream • FilterInputStream and its subclasses • do not read values from any input area • rely on one or more underlying input streams • are implementations of the design patter decorator
SequenceInputStream - Example InputStream f1 = new FileInputStream(“file1.txt“); InputStream f2 = new FileInputStream(“file2.txt“); InputStream f3 = new SequenceInputStream(f1,f2); //f3 now represents the catenation of file1 and file2 Vector fv = new Vector(); fv.addElement(f1); fv.addElement(f2); InputStream f4 = new SequenceInputStream(fv.elements()); //f4 also now represents the same catenation
client read() filter read() InputStream Filter • add behavior to the stream • DataInputStream: read bytes from the source and return them as a primitive type, e.g., public int readInt() throws IOException; • PushbackInputStream: allows a single character to be unread. • BufferedInputStream: allows the input operations to backed up over a larger range – mark(), reset() • LineNumberInputStream: deprecated
Output streams OutputStream File Output Stream Filter Output Stream Piped Output Stream Object Output Stream ByteArray Output Stream Data Output Stream Buffered Output Stream Print Stream
Output streams (cont.) abstract class OutputStream { //write a singe byte value void write(int b) throws IOException; //write an array of byte values void write(byte[] buffer) throws IOException; //flush all output from buffers void flush() throws IOException; //close this output stream void close() throws IOException; }
Output streams (cont.) • Physical output stream • ByteArrayOutputStream • FileOutputStream • PipedOutputStream • Virtual output streams • ObjectOutputStream • FilterOutputStream and its subclasses • DataOutputStream: the output equivalent DataInputStream • BufferedOutputStream: uses a buffer, values are written to the underlying stream only when the buffer becomes full or when the output is flushed • PrintStream: similar to DataOutputStream but generates a textual representation rather than a binary representation
Piped input and output • used for producer/consumer relationships • communication between producer and consumer (different threads) through a pipe • each pipe is manifested by a matched pair of stream pointers, a PipedInputStream and a PipedOutputStream, e.g., PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(in); • Example: finding all numbers that are both prime numbers and Fibonacci numbers, i.e., a number defined by the recursive relation f0 = 0, f1 = 1, fn+2 = fn + fn+1
Piped I/O - Example class FibMaker extends Thread { private DataOutputStream out; public FibMaker(DataOutputStream o) { out = o; } public void run() { try { out.writeInt(newValue); out.close(); } catch (IOException e) { return; } }
class PrimeMaker extends Thread { private DataOutputStream out; public PrimeMaker(DataOutputStream o) { out = o; } public void run() { try { out.writeInt(newValue); out.close(); } catch (IOException e) { return; } }
class PipeTest { public static void main(String[] args) { PipeTest world = new PipeTest(System.out); } private DataInputStream makeFibs() { try { PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(in); Thread fibThread = new FibMaker( new DataOutputStream(out)); fibThread.start(); return new DataInputStream(in); } catch (IOException e) { return null; } }
private DataInputStream makePrimes() {…} private PipeTest(PrintStream out) { DataInputStream fibs = makeFibs(); DataInputStream primes = makePrimes(); try { int x = fibs.readInt(); int y = primes.readInt(); while (x < 100000) { if (x == y) { out.println(…); x = fibs.readInt(); y = primes.readInt(); } else if (x < y) x = fibs.readInt(); else y = primes.readInt(); } } catch (IOException e) { System.exit(0); } }
Character Streams • Reader / Writer mirror the functionality provided by the classes InputStream and OutputStream • 8-bit bytes versus 16-bit Unicode character values • Physical Reader / Writer • CharArrayReader / Writer • StringReader / Writer • FileReader / Writer • PipedReader / Writer • Virtual Reader / Writer • BufferedReader / Writer • FilterReader / Writer • PrintWriter • InputStreamReader / OutputStreamWriter act as filter for streams, i.e., they convert streams to character streams, e.g., FileInputStream f = new FileInputStream(“fileName“); InputStreamReader r = new InputStreamReader(f);
Reader CharArray Reader InputStream Reader Filter Reader Piped Reader String Reader Buffered Reader LineNumber Reader File Reader Pushback Reader Writer CharArray Writer OutputStream Writer Filter Writer Print Writer Buffered Writer Piped Writer String Writer File Writer
StreamTokenizer • StreamTokenizer is neither an InputStream nor a Reader • provides a useful mechanism for breaking a textual file into a sequence of tokens. • Example: “23-skidoo, kid!” yields the output: number: 23.0 token: - word: skidoo token: , word: kid token: !
Reader r = new InputStreamReader(System.in); StreamTokenizer tok = new StreamTokenizer(r); try { while (tok.nextToken() != tok.TT_EOF) { switch (tok.ttype) { case tok.TT_NUMBER: System.out.println(“number: “ + tok.nval); break; case tok.TT_EOL: System.out.println(“end of line.“); break; case tok.TT_WORD: System.out.println(“word: “ + tok.sval); break; default: System.out.println(“token: “ + (char) tok.ttype); break; } } } catch (IOException e) {}
Random Access I/O • RandomAccessFile • can read & write at same time • implements DataInput & DataOutput • interfaces which are also implemented by DataInputStream and DataOutputStream, respectively • changing current I/O position • seek(l) moves the read/write position to the l-th byte counting from the beginning of the file • skipBytes(i) moves the read/write position i bytes relative to the current position • storing serialized objects in random access files • Idea: write object as size followed by serialized version • Implementation: X. Jia, Object-Oriented Software Development using Java, 8.4.4
Examples • copy a file (unfiltered, byte) try { FileInputStream in = new FileInputStream(“source“); FileOutputStream out = new FileOutputStream(“target“); int val = in.read(); while (val != -1) { out.write(val); val = in.read(); }; in.close(); out.close(); } catch (IOException e) {}
Examples • copy a file (buffered Reader / Writer) try { FileReader fin = new FileReader(“source“); BufferedReader in = new BufferedReader(fin); FileWriter fout = new FileWriter(“target“); BufferedWriter out = new BufferedWriter(fout); String str = in.readLine(); while (str != null) { out.write(str); str = in.readLine(); }; in.close(); out.close(); } catch (IOException e) {}
Design Pattern – Iterator • aka Cursor • a behavioral pattern • intent: • allow sequential access to elements of an aggregate without exposing underlying representation • motivation: • want to be able to access elements of an aggregate object without exposing internal structure • want to use several different traversals • want different traversals pending on same list
Aggregate CreateIterator() Iterator First() Next() IsDone() CurrentItem() ConcreteAggregate CreateIterator() Iterator - ModelGamma et al: “Design Patterns: elements of reusable object-oriented software”, p.259 Client ConcreteIterator return new ConcreteIterator(this)
use: • access aggregate object’s contents without exposing internal representation • support multiple traversals of aggregate objects • provide uniform interface for traversing different structures • model • consequences: • supports variations in traversal of aggregate • simplified aggregate interface • more than one traversal can be pending on an aggregate • considerations: • internal versus external iterators • Iterator<E> interface • void forEach(Consumer<? super T> action) method • who defines traversal algorithm
Iterators • based on Iterator Design Pattern • Iterator public interface Iterator<E> { public boolean hasNext(); public E next(); public void remove(); } • iterator() in Collection • sequential traversal • Enumeration public interface Enumeration<E> { public boolean hasMoreElements(); public E nextElement(); } • functionality of this interface is duplicated by the Iterator interface • new implementations should consider using Iterator in preference to Enumeration
Iterators (cont.) • ListIterator public interface ListIterator<E> extends Iterator<E> { public void add(E o); public boolean hasPrevious(); public E previous(); public int nextIndex(); public int previousIndex(); public void set(E o); } • listIterator() in List • forward and backward sequential traversal
Iterators (cont.) • iterating through Map views • views • key set • value collection • entry set (nested interface Map.Entry) public static interface Map.Entry<K,V> { public K getKey(); public V getValue(); public V setValue(V v); }
Design Pattern - Factory • a creational pattern • intent: • To define an interface for creating objects but let subclasses decide which class to instantiate and how • motivation: • Display classes for different sorting algorithms • SortDisplayFactory creates suitable instance depending on the algorithm actually used
Factory createProduct() ConcreteFactory createProduct() Factory - Model Product Creates ConcreteProduct
Design pattern - Abstract Factory • aka Kit • a creational pattern • intent: • provide interface for creating families of related objects without specifying concrete representation • motivation: • toolkit that supports multiple standards • e.g. look and feel of widgets • define WidgetFactory that declares interface for each kind of widget • concrete subclasses implement widgets for different look and feel standards • clients call operations in WidgetFactory, remaining independent of actual look and feel
AbstractFactory CreateProductA() CreateProductB() ConcreteFactory1 CreateProductA() CreateProductB() ConcreteFactory2 CreateProductA() CreateProductB() Abstract Factory – ModelGamma et al: “Design Patterns: elements of reusable object-oriented software”, p.88 Client AbstractProductA ProductA1 ProductA2 AbstractProductB ProductB2 ProductB1
use: • system should be independent of how products are created, composed and represented • family of products designed to be used together • want to provide library of products and reveal only interfaces not implementation • model • consequences • isolates concrete classes • easy to exchange product “families” • promotes consistency among products • difficult to support new kinds of products
Design pattern - Command • aka Action • a behavioral pattern • intent: • To encapsulate an action as an object, so that actions can be passed as parameters, queued, and possible undone • Use the Command design pattern • when actions need to be passed as parameters. • when actions need to be queued and then executed later. • when actions can be undone.
Command ConcreteCommand Reciever execute() execute() action() reciever->action() Command - Structure Invoker Client create receiver
Command (cont.) • use: • parameterize objects by actions to perform • specify, queue, and execute requests at different times • support undo • consequences • command are first-class objects • you can assemble commands into a composite command (design pattern – composite) • easy to add new commands
Design pattern - Observer • aka Dependents, Publish-and-Subscribe • a behavioral pattern • intent: • define dependencies between objects • when an object changes state, ensure all dependents are notified and updated • motivation: • need to maintain consistency among cooperating classes • e.g. MVC GUI model • multiple views of same data • multiple windows on same text file • subject • observers
a b c x 60 30 10 y 50 30 20 z 80 10 10 b c a a = 50% b = 30% c = 20% Model-View-Controller Observers a b c change notification requests, modifications Subject
use: • abstraction has two aspects, one dependent on the other • change to an object requires changing an unknown number of others • object needs to notify other objects without knowing details about them • consequences • abstract coupling between Subject and Observer • broadcast communication • unexpected updates • considerations • mapping subjects to observers • observing more than one subject • triggering the update • deleted subjects • self-consistent state in subject • how much information to send on update
Subject Attach(Observer) Detach(Observer) Notify() Observer Update() ConcreteSubject GetState() SetState() subjectState ConcreteObserver Update() observerState return subjectState for all o in observers { o->Update() } observerState = subject->GetState() Observer - Structure observers subject
Observer - Interaction aConcreteSubject anotherConcreteObserver aConcreteObserver SetState() Notify() Update() GetState() Update() GetState()
Design Pattern – Strategy • aka Policy • a behavioral pattern • intent: • allow different variants of an algorithm • motivation: • different traversals for sorted aggregates based on different orderings • it is difficult to add new orderings or vary existing once when they are an integral part of the traversal
Context ContextInterface() Strategy AlgorithmInterface() ConcreteStrategyB AlgorithmInterface() ConcreteStrategyC AlgorithmInterface() ConcreteStrategyA AlgorithmInterface() Strategy - ModelGamma et al: “Design Patterns: elements of reusable object-oriented software”, p.315
use: • many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many behaviors. • you need different variants of an algorithm. • an algorithm uses data that clients shouldn’t know about. • a class defines many behaviors, and these appear as multiple conditional statements in its operations. • model • consequences: • hierarchies of strategies classes define a family of algorithms or behaviors for contexts to reuse. • an alternative to subclassing • eliminates conditional statements • choice of implementations • considerations: • clients must be aware of different strategies • communication overhead between Strategy and Context • increased number of objects
Ordering and Sorting • order (partial order) • total order versus strictly partial order • natural order • by implementing Comparable interface • imposed order • by use of Comparator • Comparable • compareTo • parameter: a.compareTo(b) • result • total order • consistency with equals
Comparator public interface Comparator<T> { public int compare(T o1, T o2); public boolean equals(Object obj); } • Strategy Design Pattern • compare • parameters c.compare(a,b) • result • total order • consistency with equals
Design pattern - Composite • Intent: • compose objects into tree structures to represent part-whole hierarchies. • use the composite pattern when • you want to represent part-whole hierarchies of objects • you want clients to be able to ignore the difference between compositions of objects and individual objects
Component Operation() Add(c : Component) Remove(c : Component) GetChildren() : Collection Leaf Operation() Composite - Structure Client children Component Operation() Add(c : Component) Remove(c : Component) GetChildren() : Collection forall g in children g.Operation();
Example public abstract class Tree<E> implements Iterable<E> { private E element; public Tree(E element) { this.element = element; } public E getElement() { return element; } public abstract boolean contains(E element);
Example (cont’d) public boolean containsAll(Collection<E> collection) { boolean result = true; for(E element : collection) result &= contains(element); return result; } public abstract int size(); public abstract int depth(); public Iterator<E> iterator() { return new DfsTreeIterator<E>(this); } }