You are on page 1of 71

Stream Based I/O

• Implementation of Byte stream,


• Character stream,
• Buffered stream,
• Data stream,
• Object stream and
• File I/O
Filter Streams
• A filter is a high-level stream that provides additional
functionality to an underlying stream to which it is chained.
• The data from the underlying stream is manipulated in some
way by the filter.
1. The FilterInputStream and FilterOutputStream classes,
together with their subclasses, define input and output filter
streams.
2. Subclasses BufferedInputStream and BufferedOutputStream
implement filters that respectively buffer input from, and
output to, the underlying stream.
3. Subclasses DataInputStream and DataOutputStream
implement filters that allow Java primitive values to be read
and written respectively to and from an underlying stream.
I/O of Java Primitive Values
• The java.io package contains two interfaces:
– DataInput and
– DataOutput,
that streams can implement to allow reading and
writing of binary representations of Java primitive
values (boolean, char, byte, short, int, long, float,
double).
DataInput, DataOutput interface methods

• writeX() - Methods for writing binary


representations of Java primitive values, where X is
any Java primitive datatype.
• readX() - Methods for reading binary representations
of Java primitive values
• The filter streams DataOutputStream and
DataInputStream implement DataOutput and
DataInput interfaces respectively, and can be used to
write and read binary representations of Java
primitive values to and from an underlying stream.
• Both the writeX() and readX() methods throw an
IOException in the event of an I/O error.
• Bytes can also be skipped from a DataInput stream,
using the skipBytes(int n) method which skips n
bytes.
• The following constructors can be used to set
up filters for reading and writing Java primitive
values respectively from an underlying stream:
– DataInputStream(InputStream in)
– DataOutputStream(OutputStream out)
Stream Chaining
To write the binary representation of Java primitive
values to a file, the following procedure can be used
1. Create a FileOutputStream:
FileOutputStream outputFile = new FileOutputStream("primitives.data");
2. Create a DataOutputStream which is chained to the FileOutputStream:
DataOutputStream outputStream = new DataOutputStream(outputFile);
3. Write Java primitive values using relevant writeX() methods:
outputStream.writeBoolean(true);
outputStream.writeChar('A'); // int written as Unicode char
outputStream.writeByte(Byte.MAX_VALUE);
outputStream.writeShort(Short.MIN_VALUE);
outputStream.writeInt(Integer.MAX_VALUE);
outputStream.writeLong(Long.MIN_VALUE);
outputStream.writeFloat(Float.MAX_VALUE);
outputStream.writeDouble(Math.PI);
4. Close the filter stream, which also closes the underlying stream:
outputStream.close();
To read the binary representation of Java primitive values from a file the
following procedure can be used.
1. Create a FileInputStream:
FileInputStream inputFile = new FileInputStream("primitives.data");
2. Create a DataInputStream which is chained to the FileInputStream:
DataInputStream inputStream = new DataInputStream(inputFile);
3. Read Java primitive values in the same order they were written out, using
relevant readX() methods :
boolean v = inputStream.readBoolean();
char c = inputStream.readChar();
byte b = inputStream.readByte();
short s = inputStream.readShort();
int i = inputStream.readInt();
long l = inputStream.readLong();
float f = inputStream.readFloat();
double d = inputStream.readDouble();
4. Close the filter stream, which also closes the underlying stream:
inputStream.close();
Buffered Byte Streams
• The filter classes BufferedInputStream and
BufferedOutputStream implement buffering of bytes for
input and output streams, respectively.
• Data is read and written in blocks of bytes, rather than a
single byte at a time.
• Buffering can enhance performance significantly.
• These filter classes only provide methods for reading
and writing bytes.
• A buffering filter must be chained to an underlying
stream:
BufferedInputStream(InputStream in)
BufferedOutputStream(OutputStream out)
Writing of binary representations of Java primitive
values to a file, bytes can be buffered

• FileOutputStream outputFile = new


FileOutputStream("primitives.data");
• BufferedOutputStream bufferedOutput = new
BufferedOutputStream(outputFile);
• DataOutputStream outputStream = new
DataOutputStream(bufferedOutput);
Reading of binary representations of Java primitive
values froma file, bytes can be buffered

• FileInputStream inputFile = new


FileInputStream("primitives.data");
• BufferedInputStream bufferedInput = new
BufferedInputStream(inputFile);
• DataInputStream inputStream = new
DataInputStream(bufferedInput);
Character Streams: Readers and Writers
• A character encoding is a scheme for representing
characters.
• Java programs represent characters internally in the 16-bit
Unicode character encoding, but the host platform might
use another character encoding to represent characters
externally.
• For example, the ASCII (American Standard Code for
Information Interchange) character encoding is widely used
to represent characters on many platforms.
• However, it is only one small subset of the Unicode
standard.
• The abstract classes Reader and Writer are the roots of the
inheritance hierarchies for streams that read and write
Unicode characters using a specific character encoding.
• A reader is an input character stream that
reads a sequence of Unicode characters.
• A writer is an output character stream that
writes a sequence of Unicode characters.
• Character encodings are used by readers and
writers to convert between external encoding
and internal Unicode characters.
Readers use the following methods for reading
Unicode characters:

– int read() throws IOException


– int read(char cbuf[]) throws IOException
– int read(char cbuf[], int off, int len) throws IOException
• read() methods read an int in the range 0 to 65535
(0x0000– 0xFFFF), i.e. a Unicode character.
• The value –1 is returned if the end of file has been
reached.
– long skip(long n) throws IOException
• A reader can skip over characters using the skip()
method.
Writers use the following methods for writing
Unicode characters:
– void write(int c) throws IOException
• The write() method takes an int as argument, but only
writes out the least significant 16 bits.
– void write(char[] cbuf) throws IOException
– void write(String str) throws IOException
– void write(char[] cbuf, int off, int len) throws IOException
– void write(String str, int off, int len) throws IOException
• These methods write the characters from an array of
characters or a string.
– void close() throws IOException
– void flush() throws IOException
Character Encodings
• Every platform has a default character
encoding that can be used by readers and
writers to convert between external encodings
and internal Unicode characters.
• Readers and writers can also explicitly specify
which encoding schemes to use for reading
and writing.
OutputStreamWriter
• The class OutputStreamWriter implements writers that can
translate Unicode characters into bytes, using a character
encoding and write the resulting bytes to a byte output
stream.
– OutputStreamWriter(OutputStream out)
InputStreamReader
• The class InputStreamReader implements readers that can
read bytes in the default character encoding or a particular
character encoding from an input stream, and translate them
to Unicode characters:
– InputStreamReader(InputStream in)
Print Writers
• The capabilities of the OutputStreamWriter and the
InputStreamReader classes are limited, as they primarily write
and read characters.
• In order to write textual representation of Java primitive
values and objects, a PrintWriter should be chained to either
a writer or a byte output stream, using one of the following
constructors:
– PrintWriter(Writer out)
– PrintWriter(Writer out, boolean autoFlush)
– PrintWriter(OutputStream out)
– PrintWriter(OutputStream out, boolean autoFlush)
• The PrintWriter class provides the following methods for
writing textual representation of Java primitive values and
objects:
Writing Text Files
• When writing text to a file using the default character
encoding, the following three procedures for setting up a
PrintWriter are equivalent.
Reading Text Files
• Java primitive values and objects cannot be
read directly from their textual
Representation.
• Characters must be read and converted to the
relevant values explicitly.
• One common strategy is to write lines of text
and tokenize the characters as they are read, a
line at a time.
Buffered Character Streams
• To improve the efficiency of I/O operations, readers and
writers can buffer their input and output.
• For this purpose, a BufferedWriter or a BufferedReader can be
chained to the underlying writer or reader, respectively:
– BufferedWriter(Writer out)
– BufferedWriter(Writer out, int size)
– BufferedReader(Reader in)
– BufferedReader(Reader in, int size)
– The default buffer size is used, unless
• The BufferedReader class provides the method
readLine() to read a line of text from the underlying
reader:
– String readLine() throws IOException
• The null value is returned when the end of input is
reached.
• The returned string must explicitly be converted to
other values.
Using Buffered Writers
Using Buffered Readers
Terminal I/O
• The standard output stream (usually the
screen) is represented by the PrintStream
object System.out.
• The standard input stream (usually the
keyboard) is represented by the InputStream
object System.in.
• In other words, it is a byte input stream.
• In order to read and translate characters correctly
and efficiently, System.in should be chained to an
InputStreamReader that in turn should be buffered:
FileReader,FileWriter,
BufferedReader,BufferedWriter
DataInputStream, DataOutputStream
DataOutputStream and DataInputStream

• DataOutputStream and DataInputStream enable


you to write or read primitive data to or from a
stream.
• They implement the DataOutput and DataInput
interfaces, respectively.
• These interfaces define methods that convert
primitive values to or from a sequence of bytes.
• These streams make it easy to store binary data,
such as integers or floating-point values, in a file.
DataOutputStream
• DataOutputStream(OutputStream
outputStream)
• final void writeDouble(double value) throws
IOException
• final void writeBoolean(boolean value) throws
IOException
• final void writeInt(int value) throws
IOException
DataInputStream
• DataInputStream(InputStream inputStream)
• double readDouble( ) throws IOException
• boolean readBoolean( ) throws IOException
• int readInt( ) throws IOException
Example
class DataIODemo {
public static void main(String args[]) throws IOException {
FileOutputStream fout = new FileOutputStream("Test.dat");
DataOutputStream out = new DataOutputStream(fout);
out.writeDouble(98.6);
out.writeInt(1000);
out.writeBoolean(true);
out.close();
FileInputStream fin = new FileInputStream("Test.dat");
DataInputStream in = new DataInputStream(fin);
double d = in.readDouble();
int i = in.readInt();
boolean b = in.readBoolean();
System.out.println("Here are the values: " +
d + " " + i + " " + b);
in.close();
}
}
Reader and Writer
• Reader is an abstract class that defines Java’s
model of streaming character input. It
implements the Closeable and Readable
interfaces.
• Writer is an abstract class that defines
streaming character output. It implements the
Closeable, Flushable, and Appendable
interfaces
FileReader and FileWriter
• The FileReader class creates a Reader that you can use to
read the contents of a file. Its two most commonly used
constructors are shown here:
– FileReader(String filePath)
– FileReader(File fileObj)
• FileWriter creates a Writer that you can use to write to a
file. Its most commonly used constructors are shown here:
– FileWriter(String filePath)
– FileWriter(String filePath, boolean append)
– FileWriter(File fileObj)
– FileWriter(File fileObj, boolean append)
Reader methods
Writer Methods
File Reader Example
import java.io.*;
class FileReaderDemo {
public static void main(String args[]) throws IOException {
FileReader fr = new FileReader("FileReaderDemo.java");
BufferedReader br = new BufferedReader(fr);
String s;
while((s = br.readLine()) != null) {
System.out.println(s);
}
fr.close();
}
}
File Writer Example
class FileWriterDemo {
public static void main(String args[]) throws IOException {
String source = "Now is the time for all good men\n"
+ " to come to the aid of their country\n"
+ " and pay their due taxes.";
char buffer[] = new char[source.length()];
source.getChars(0, source.length(), buffer, 0);
FileWriter f0 = new FileWriter("file1.txt");
for (int i=0; i < buffer.length; i += 2) {
f0.write(buffer[i]);
}
f0.close();
FileWriter f1 = new FileWriter("file2.txt");
f1.write(buffer);
f1.close();
FileWriter f2 = new FileWriter("file3.txt");
f2.write(buffer,buffer.length-buffer.length/4,buffer.length/4);
f2.close();
}
}
BufferedWriter Class
• Java BufferedWriter class is used to provide
buffering for Writer instances. It makes the
performance fast. It inherits Writer class.
The buffering characters are used for
providing the efficient writing of single 
BufferedWriter(Writ It is used to create a buffered character output
er wrt) arrays, characters, and strings.
stream that uses the default size for an output
buffer.
BufferedWriter(Writ It is used to create a buffered character output
er wrt, int size) stream that uses the specified size for an output
buffer.
BufferedWriter Class
Method Description

void newLine() It is used to add a new line by writing a line


separator.

void write(int c) It is used to write a single character.

void write(char[] cbuf, int It is used to write a portion of an array of


off, int len) characters.

void write(String s, int off, It is used to write a portion of a string.


int len)
void flush() It is used to flushes the input stream.

void close() It is used to closes the input stream


BufferedWriter
import java.io.*;  
public class BufferedWriterExample {  
public static void main(String[] args) throws Exception {     
    FileWriter writer = new FileWriter("D:\\testout.txt");  
    BufferedWriter buffer = new BufferedWriter(writer);  
    buffer.write("Welcome.");  
    buffer.close();  
    System.out.println("Success");  
    }  
}  
BufferedReader
• Java BufferedReader class is used to read the
text from a character-based input stream. It
can be used to read data line by line by
readLine() method. It makes the performance
Constructor Description
fast. It inherits Reader class.
BufferedReader(Read It is used to create a buffered character input
er rd) stream that uses the default size for an input
buffer.
BufferedReader(Read It is used to create a buffered character input
er rd, int size) stream that uses the specified size for an
input buffer.
BufferedReader
Method Description
int read() It is used for reading a single character.
int read(char[] cbuf, It is used for reading characters into a portion of
int off, int len) an array.
boolean It is used to test the input stream support for the mark
markSupported() and reset method.
String readLine() It is used for reading a line of text.
boolean ready() It is used to test whether the input stream is ready to be
read.
long skip(long n) It is used for skipping the characters.
void reset() It repositions the stream at a position the mark method
was last called on this input stream.
void mark(int It is used for marking the present position in a stream.
readAheadLimit)
void close() It closes the input stream and releases any of the
system resources associated with the stream.
BufferedReader
public class BufferedReaderExample {  
    public static void main(String args[])throws Exception{    
          FileReader fr=new FileReader("D:\\testout.txt");    
          BufferedReader br=new BufferedReader(fr);    
            int i;    
          while((i=br.read())!=-1){  
          System.out.print((char)i);  
          }  
          br.close();    
          fr.close();    
    }    
}    
Serialization
Serialization
• Serialization is the process of writing the state
of an object to a byte stream.
• The output of a program is saved to a
persistent storage area, such as a file.
• We can also restore these objects by using the
process of deserialization.
RMI
• RMI- Remote method inovocation
– A Java object on one machine can call a method
present on other machine
– Object may is supplied as an argument to that
remote method.
– The sending machine serializes the object and
transmits it.
– The receiving machine deserializes it.
ObjectOutputStream
• ObjectOutputStream
– The ObjectOutputStream class extends the OutputStream
class and implements the ObjectOutput interface.
– It is responsible for writing objects to a stream.
– A constructor of this class is
• ObjectOutputStream(OutputStream outStream) throws IOException
– The ObjectOutput interface extends the DataOutput interface
and supports object serialization.
void close( )
void flush( )
void writeObject(Object obj)
final void writeObject(Object obj)
ObjectInputStream
• The ObjectInputStream class extends the InputStream class
and implements the ObjectInput interface. ObjectInputStream
is responsible for reading objects from a stream.
• Aconstructor of this class is
– ObjectInputStream(InputStream inStream) throws IOException
– The ObjectInput interface extends the DataInput interface and
defines the methods
int available( )
void close( )
Object readObject( )
final Object readObject( )
SETS
Sets
• The Set interface in the standard Java library has the same
methods as the Collection interface.
• A set does not admit duplicates. If we add an element to a
set that is already present, the insertion is ignored.
• The HashSet and TreeSet classes implement the Set interface.
• These two classes provide set implementations based on two
different mechanisms, called hash tables and binary search
trees.
• Both implementations arrange the set elements so that
finding, adding, and removing elements is efficient, but they
use different strategies.
Hash Table
• The basic idea of a hash table is simple.
• Set elements are grouped into smaller collections of elements
that share the same characteristic.
• We can imagine a hash set of books as having a group for each
color, so that books of the same color are in the same group.
• Hash tables use integer values (called hash codes) that can be
computed from the elements.
• In order to use a hash table, the elements must have a method to
compute those integer values. This method is called hashCode.
• The elements must also belong to a class with a properly defined
equals method
TreeSet
• The TreeSet class uses a different strategy for arranging
its elements.
• Elements are kept in sorted order
• For example, a set of books might be arranged by
height, or alphabetically by author and title.
• The elements are not stored in an array—that would
make adding and removing elements too inefficient.
• Instead, they are stored in nodes, as in a linked list.
However, the nodes are not arranged in a linear
sequence but in a tree shape
• In order to use a TreeSet, it must be possible
to compare the ele ments and determine
which one is “larger”.
• We can use a TreeSet for classes such as String
and Integer that implement the Comparable
interface
Construction a HashSet or TreeSet
• store the reference in a Set<String> variable,
– either as
Set<String> names = new HashSet<String>();
or
Set<String> names = new TreeSet<String>();
Maps
• A map allows you to associate elements from a key set with
elements from a value collection.
• Java library has two implementations for the Map interface:
HashMap and TreeMap.
• Example:
– Store the reference to the map object in a Map reference:
Map<String, Color> favoriteColors = new HashMap<String, Color>();
– Use the put method to add an association:
favoriteColors.put("Juliet", Color.RED);
– The get method returns the value associated with a key.
Color julietsFavoriteColor = favoriteColors.get("Juliet");
• To remove an association, call the remove
method with the key:
favoriteColors.remove("Juliet");

You might also like