94.204* Object-Oriented Software Development

computerharpySoftware and s/w Development

Dec 2, 2013 (3 years and 8 months ago)

97 views

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

1

94.204* Object
-
Oriented Software Development


Unit 13

I/O Stream Hierarchy


Case Study of an Inheritance Hierarchy










revised January 30, 2001

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

2

I/O Streams


All input and output in Java is based on streams.


A stream is a flow of data with a reader on one end and a writer on
the other end




Streams are sequences of bytes


Streams in Java are one
-
way.


A Writer = Anything that can send a sequence of bytes


A Reader = Anything that can receive a sequence of bytes


Preview ! Seamless interchange between terminals, files,
URLs, blocks of memory, sockets (remote computers)


Writer

Reader

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

3


In the package java.io, there is an inheritance hierarchy of streams
supported








InputStream and OutputStream are abstract classes


Concrete subclasses must be provided; Instantitate these.


Stream are objects to/from which data are sent/received.


Because all I/O objects are subclassed from InputStream &
OutputStream, they can be used interchangeably (type
-
casting along class
hierarchy)

Java I/O Stream Classes

InputStream

OutputStream

ConcreteInputSubclasses

ConcreteOutputSubclasses

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

4

Java.io.InputStream


Full UML of java.io.InputStream

java.io.InputStream


read():int

read(:byte[]):int

read(:byte[],:off:int,len:int):int

skip(n:long):long

available():int

close():int

reset()

mark(readLimit:int)

markSupported():boolean



read() is the only abstract method

(UML :
Italics

for abstract)



read() is the lowest
-
level interface for
all streams : a flow of byte
-
level data.



Other read methods are implemented in
terms of this one



Other methods provide default
behaviour, to be overridden by
subclasses.

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

5

Java.io.OutputStream


Full UML of java.io.OutputStream

java.io.OutputStream


write():int

write(:byte[]):int

write(:byte[],:off:int,len:int):int

flush()



write() is the only abstract method



Other write methods are
implemented in terms of this one.



Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

6

Java I/O Class Design



The Problem :


Although everything is ultimately a series of bytes, we don’t want to
manipulate bytes; We want to program at a higher level (abstraction!)


There is a great variety of scenarios to cover


Data abstraction : Instead of bytes, let’s read int, float, char


Higher
-
level : As well as the primitive types, we want to support
I/O of classes, such as String but also user
-
defined classes


Sources : Terminal, File, URL, ….sockets


Behaviours : Buffering, look
-
ahead, random
-
access


Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

7

Java I/O Class Design


The Java approach is a pluggable solution


A Layered approach based on
stream wrapper

or
filters

:


Java supplies you with a whole slew of filters (as classes), where
each class adds one type of behaviour. You can then layer (or
wrap) these filters in any pattern to achieve the kind of behaviour
you require.






In the next slides, we look at the major parts of the full I/O hierarchy, but
in stages. The breakdown is artificial and serves only to break discussion
into manageable pieces.


We also look first at the Input side, then follow with the Output


File

Buffered

Data

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

8

Java Input Class Hierarchy


Part I : At the first level of the Input hierarchy are a set of concrete
subclasses that can be viewed as the “source”


Allows you to connect a stream to a particular type of source.

InputStream

FileInputStream

PipedInputStream

StringBufferInputStream

ObjectInputStream

ByteArrayInputStream

Reading from sockets

(remote communication)

Reading from files

Reading from string buffers

Reading from byte array(memory)

Reading from any object

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

9

Java Input Class Hierarchy

Example : Using one of the “source” InputStream subclasses.



Suppose we wish to read from a file :


FileInputStream istream = new FileInputStream("t.tmp");


istream.read();


// FileInputStream must provide implementation

istream.read(bytes,n);



// Could have used InputStream’s version,


// FileInputStream overrides for efficiency



You can only read bytes or arrays of bytes from this file.


Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

10

Java Input Class Hierarchy


Part II : There is a second level of the I/O hierarchy which is collectively
called the filter or stream wrappers


Filters add behaviour to the stream

InputStream

FileInputStream

PipedInputStream

StringBufferInputStream

ObjectInputStream

ByteArrayInputStream

FilterInputStream

It is another abstract class.

In order to learn how to use it,

We must look at
its

concrete

Subclasses.

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

11

Java Input Class Hierarchy


Part II : FilterInputStream

InputStream

PushbackInputStream

BufferedInputStream

DataInputStream

CheckedInputStream

LineNumberInputStream

FilterInputStream

DigestInputStream

InflaterInputStream

GZIPInputStream

ZipInputStream

JarInputStream

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

12

Summary of Input Filter Classes


BufferedInputStream : Adds the ability to buffer, and support for
mark() and reset() methods.


PushBackInputStream : Adds the ability to “unread” something.


DataInputStream : Support for primitive data types


LineNumberInputStream : Keeps track of the current line number
where a line is a sequence of bytes followed by a CR


CheckedInputStream :Adds the ability to maintain a checksum on the
data (for data integrity)


DigestInputStream : A security mechanism for reading messages
“digested” in a transparent stream of bits.


InflaterInputStream : Allows the reading of compressed data.

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

13

Java Input Class Hierarchy

Example : Using one of the “filter” InputStream subclasses.



Continuing from the previous example, suppose we wish to read data
from a file :


FileInputStream istream = new
FileInputStream("t.tmp");

DataInputStream dstream = new
DataInputStream(istream);


int i = dstream.readInt();

char c = dstream.readChar();

String line = dstream.readLine();


Wrapping the FileInputStream

Into a DataInputStream !

Now can read integers,

Characters, whole lines,

Instead of just bytes.

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

14

Stream Wrapping

How does Stream Wrapping Work ?



Take a look at any of the constructors for the filter classes.


eg. public DataInputStream(InputStream in)



The constructor is part of a chain :



Input

:

The parameter to the constructor is an inputstream.





But you don’t have to use an InputStream; you can use any




subclass of InputStream.



Output

: The object created by the constructor is a DataInputStream





(which is itself a subclass of InputStream and thus could be


used for further wrapping in another filter class).


Because all the input subclasses inherit from java.io.InputStream, they can be
used as the input in the constructor of another stream.

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

15

Java Output Class Hierarchy


The Output Class Hierarchy follows as similar format

OutputStream

FileOutputStream

PipedOutputStream

ObjectOutputStream

ByteArrayOutputStream

Writing to sockets

(remote communication)

Writing to files

Writing to byte array(memory)

Writing to any object

FilterOutputStream

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

16

Java Output Class Hierarchy


Part II : FilterOutputStream

OutputStream

BufferedOutputStream

DataInputStream

CheckedOutputStream

DigestOutputStream

FilterInputStream

PrintStream

DeflaterOutputStream

GZIPOutputStream

ZipOutputStream

JarOutputStream

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

17

I/O Examples : Writing Objects to a file


FileOutputStream ostream = new
FileOutputStream("t.tmp");


ObjectOutputStream p = new ObjectOutputStream(ostream);


int i = 5;

p.writeInt(i);

p.writeObject( “Writing a String object” );

p.writeUTF(“Writing a string as primitive data”);

p.writeObject( new Date (2001,1,21));

ostream.close();

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

18

Detour About Object Streams : Serializable


When you write an object to an OutputStream (eg. To a file), what
information must be stored in order for it to be read back from an
InputStream ?



Object Type


Data that describes the current state of the object




Reading and writing objects involves a process called serialization.


Applied only to objects, not to primitive data types (which use
DataInput/Output interfaces)


Saves objects in a particular file format (Details are not important
in order to use, but interested people are referred to Core Java)


Java provides default serialization. In order to use this, your class
must simply identify itself by implementing java.io.Serializable




Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

19

Detour About Object Streams : Serializable

package java.io;

/** … The serialization interface has no methods
or fields and serves only to identify the
semantics of being serializable. To allow
subtypes of non
-
serializable classes to be
serialized, the subtype may assume
responsibility for saving and restoring the
state of the supertype's public, protected, and
(if accessible) package fields.


**/

public interface Serializable {



static final long serialVersionUID =
1196656838076753133L;

}


Like Cloneable, this is a “tagging” interface (no methods)


JVM supplies a default serialization process to any objects tagged as
Serializable; You don’t have to provide any implementation yourself if
the default is fine.

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

20

Detour About Object Streams : Serializable

You can also override the serializing methods, and provide your own




private void readObject(ObjectInputStream in)



throws IOException, ClassNotFoundException;



private void writeObject(ObjectOutputStream out)



throws IOException;



These will override the default, reading & writing the object’s data

-

but not its superclass’s.


In order to provide a completely new serialization mechanism, you must
implement java.io.Externalizable


Why ?


Security : Java’s serialization format is well
-
known and can be hacked.


But that’s a whole other course !

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

21

Java I/O Class Hierarchy : Interfaces


Suppose we now want to read/write from/to a Random Access file


Behaviour : Access any specified location in a file



Solution ?









Weakness :


Random

access is not a stream because it is not a sequence of bytes;


Moreover, a random access file permits both read and write!


You can’t subclass it from Input/OutputStream yet they do indeed share
many behaviours (eg. Reading/writing primitive data types), suggesting
that a better solution is by way of interfaces.

InputStream

OutputStream

RandomAccess

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

22

Java I/O Class Hierarchy : Interfaces


Quoting from Jbuilder : The DataInput interface provides for reading
bytes from a binary stream and reconstructing from them data in any of
the Java primitive types.



InputStream

FilterInputStream

DataInputStream

DataInput

OutputStream

FilterOutputStream

DataOutputStream

DataOutput

RandomAccessFile

Shares behaviour

With IOStream

Has Own Behaviour Too :


Both Input & Output!

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

23

Java I/O Class Hierarchy


A second look at the ObjectInput/OutputStreams


When reading/writing objects, you are ultimately reading/writing
primitive data types


You often want to read both primitive types and objects from a
stream.


Conclusion : Reading/writing objects shares and extends behaviour of
reading/writing data




ObjectInputStream

ObjectInput

DataInput

Quoting from Jbuilder : ObjectInput
extends

the DataInput interface to include the reading
of objects. DataInput includes methods for
the input of primitive types, ObjectInput
extends that interface to include objects,
arrays, and Strings.

Similarly for Output

Copyright(c) Systems and Computer Engineering, Carleton Univeristy,
2001

24

Reader/Writer Class Hierarchy.






InputStream and OutputStream operate on sequences of bytes.



Used for reading/writing binary data.



eg. Files are binary files


Cannot view them for text editors.



There is a whole separate hierarchy, mostly duplicated, that operates
on UNICODE text


eg. Files are text files


Can view with a text editor.



InputStream

OutputStream

Reader

Writer