You are on page 1of 17

APC Ray Polytechnic

188, Raja Subodh Chandra Mallick Rd, Jadavpur,


Kolkata - 700032
Department of Computer Science & Technology
3rd year – 5th semester
e-Contents : Java Programming
Unit 6 : Streams & File I/O

Developed By
Prosenjit Roy
Lecturer In Computer Science & Technology
APC Ray Polytechnic
188, Raja Subodh Chandra Mallick Rd, Jadavpur,
Kolkata - 700032
Java Programming : Unit 6

Contents

Subunit Page No

6.1 Stream Classes 5


6.2 Character Stream, Byte Stream 5
6.3 Serialization 13

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 2
Java Programming : Unit 6

Streams & File i/o


Streams: An Overview:
All Java programs perform I/O through streams. A stream is an abstraction that either produces or
consumes information. A stream is linked to a physical device by the Java I/O system. All streams behave
in the same manner, even if the actual physical devices to which they are linked differ. Thus, the same I/O
classes and methods can be applied to any type of device. This means that an input stream can abstract
many different kinds of input sources - a disk file, a keyboard, a network socket, or anything of the sort.
Likewise, an output stream may refer to the console, a disk file, a network connection and so on. Streams
are a clean way employed by Java to deal with input/output without having every part of the code
understand the difference between, let’s say, for example, a keyboard and a network.

Java implements streams within class hierarchies defined in the java.io package, as we’ll see shortly.

Conceptual view of Stream:


Conceptually, a stream in Java is a path along which data flows, much like a pipe along which water
flows. It has a source (of data) and a destination (for that data) as depicted in the figure below:

Both the source and the destination may be a physical device, a programme or another stream in the same
programme.

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 3
Java Programming : Unit 6

Types of Streams:
In general, Java Streams are classified into two basic types — Input Stream and Output Stream.
 Input Stream − This type of streams extracts (i.e. reads) data from the source (keyboard, file
etc.) and sends it to the programme. The programme connects and opens an input stream on the
data source and then reads the data in serially.
 Output Stream − This type of streams takes data from the program and sends (i.e. writes) it
to the destination (console, file etc.). The programme connects and opens an output stream on the
data destination and then writes the data out serially.

In both the cases, the programme doesn’t know the details of the source and the destination.
Again, based on the data they handle, Streams are of two types − Byte Streams and Character Streams.
 Byte Streams − These handle data in bytes (8 bits) i.e., the byte stream classes read/write data
of 8 bits. Using these we can store characters, videos, audios, images etc.
 Character Streams − These handle data in 16 bit Unicode. Using these we can read and
write text data only.

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 4
Java Programming : Unit 6

6.1 Stream Classes:


Following diagram illustrates the hierarchy of some important input and output Stream classes in Java
library, i.e. the java.io package to be exact. Java puts all its Stream classes in this package.

6.2 Byte Streams and Character Streams:


Byte Streams:

Fig: Hierarchy of some important Byte Stream classes in java.io package

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 5
Java Programming : Unit 6

Java byte streams are used to perform input and output of 8-bit bytes. Though there are many classes
related to byte streams, the most frequently used classes are, FileInputStream and FileOutputStream.

Following is an example which makes use of these two classes to copy an input file into an output file:

Example:
import java.io.*;

public class CopyFile


{
public static void main(String args[]) throws IOException
{
FileInputStream in = null;
FileOutputStream out = null;

try
{
in = new FileInputStream("input.txt");
out = new FileOutputStream("output.txt");

int c;

while ((c = in.read()) != -1)


{
out.write(c);
}

}
finally
{
if (in != null)
{
in.close();
}

if (out != null)
{
out.close();
}
}
}
}

Now let's have a file input.txt with the following content:


Java is a pure object oriented programming language.

We can check it by the following command:


$type intput.txt

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 6
Java Programming : Unit 6

As a next step, we compile the above program and execute it, which will result in creating output.txt
file with the same content as we have in input.txt.
So let's put the above code in CopyFile.java file and simply do the following:
$javac CopyFile.java
$java CopyFile

To verify whether the job is done, type in the following:


$type output.txt

The output will be as follows:

Java is a pure object oriented programming language.

That means our goal is achieved.

Character Streams:

Fig: Hierarchy of some important Character Stream classes in java.io package

Java Character streams are used to perform input and output for 16-bit unicode. Though there are many
classes related to character streams but the most frequently used classes are, FileReader and FileWriter.
We can re-write the above example, which makes the use of these two classes to copy an input file
(having unicode characters) into an output file, as follows:

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 7
Java Programming : Unit 6

Example:
import java.io.*;

public class CopyFile


{
public static void main(String args[]) throws IOException
{
FileReader in = null;
FileWriter out = null;

try
{
in = new FileReader("input.txt");
out = new FileWriter("output.txt");

int c;

while ((c = in.read()) != -1)


{
out.write(c);
}
}
finally
{
if (in != null)
{
in.close();
}
if (out != null) {
out.close();
}
}
}
}

The Predefined Streams:


As we know, all Java programs automatically import the java.lang package. This package defines a class
called System, which encapsulates several aspects of the run-time environment. For example, using some
of its methods, we can obtain the current time and the settings of various properties associated with the
system. System also contains three predefined stream variables, in, out, and err. These fields are declared
as public and static within System. This means that they can be used by any other part of our program
and without reference to a specific System object.

 System.out ‒ It is an object of type PrintStream and refers to the standard output stream
which is already open and ready to accept output data. By default, this stream corresponds to the
console.

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 8
Java Programming : Unit 6

 System.in ‒ It is an object of type InputStream and refers to standard input stream which is
already open and ready to accept input data. This stream corresponds to the keyboard by default.

 System.err ‒ It is an object of type PrintStream and refers to the standard error stream,
which corresponds to the console by default.

However, these streams may be redirected to any compatible I/O device.

These are byte streams, even though they typically are used to read and write characters from and to the
console. As we will see, we can wrap these within character-based streams, if desired.

Reading Console Input:


In Java 1.0, the only way to receive console input was to use a byte stream, and older code that uses this
approach persists. Today, using a byte stream to read console input is still technically possible, but doing
so may require the use of a deprecated method, and this approach is not recommended. The preferred
method of reading console input for Java 2 is to use a character-oriented stream, which makes your
program easier to internationalize and maintain.

In Java, receiving console input is accomplished by reading from System.in. To obtain a character-based
stream that is attached to the keyboard, you wrap System.in in a BufferedReader object (which is a
character stream) to create a character stream. BufferedReader supports a buffered input stream. Its most
commonly used constructor is shown here:

BufferedReader (Reader inputReader)

Here, inputReader is the stream that is linked to the instance of BufferedReader that is being created.
Reader is an abstract class topping the character stream hierarchy. One of its concrete subclasses is
InputStreamReader, which converts bytes to characters. So an object of InputStreamReader can be
used as the actual argument of the above constructor of BufferedReader.

Now, to obtain an InputStreamReader object that is linked to System.in, use the following constructor:

InputStreamReader (InputStream ips)

Through this constructor, InputStreamReader acts as a bridge from byte streams to character streams: it
reads bytes and decodes them into characters. Thus it is the InputStreamReader that is doing the trick
here.

Now, since System.in refers to an object of type InputStream, it can be used as the actual argument of
the above constructor of InputStreamReader.

Putting it all together, the following line of code creates a BufferedReader object that is connected to the
keyboard:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

After this statement executes, br holds the reference to a character-based stream object that is linked to
the keyboard through System.in.

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 9
Java Programming : Unit 6

A Point worth noting:


If the InputStreamReader is doing the key role, why should we take the trouble of wrapping it up by
another character stream BufferedReader? The clarification is given below:

Each invocation of one of an InputStreamReader's read() methods may cause one or more bytes to
be read from the underlying byte-input stream. To enable the efficient conversion of bytes to characters,
more bytes may be read ahead from the underlying stream than are necessary to satisfy the current read
operation.

A BufferedReader reads text from a character-input stream, buffering characters so as to provide for the
efficient reading of characters, arrays, and lines. The buffer size may be specified. If not, the default size,
which is predefined, may be used. The default is large enough for most purposes.

It is therefore good practice, for top efficiency, to wrap a BufferedReader around an


InputStreamReader (or around any Reader for that matter) whose read() operations may be costly.

Reading Characters:

To read a character from a BufferedReader, we will use the read( ) method of the BufferedReader
class. Its signature is given below:

int read( ) throws IOException

Each time this read( ) is called, it reads a character from the input stream and returns it as an integer value
in the range 0 to 65535 or –1 when the end of the stream is encountered. As you can see, it can throw an
IOException.

Example:

// Reading characters from keyboard using a BufferedReader object

import java.io.*;

public class BRRead


{

public static void main(String args[]) throws IOException


{

try
{
// creating a BufferedReader object using System.in

BufferedReader br = new BufferedReader(new


InputStreamReader(System.in));

char c;

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 10
Java Programming : Unit 6
System.out.println("Enter characters, 'q' to quit.");

do {

c = (char) br.read(); // Reading characters from keyboard


System.out.println((“You Entered: “+c);

} while(c!='q');

}
catch(IOException e)
{
System.out.println("I/O Error!");
System.exit(1);
}

}
}

We now put the above code in BRRead.java and do the following:

$javac BRRead.java
$java BRRead

We will have the output as follows:

Enter characters, 'q' to quit.


i
You Entered: i
n
You Entered: n
d
You Entered: d
i
You Entered: i
a
You Entered: a
q
You Entered: q

Reading Strings:

To read a string from the keyboard, use the version of readLine( ) that is a member of the
BufferedReader class. Its prototype is shown below:

String readLine( ) throws IOException

The method readLine( ) reads a line of text. A line is considered to be terminated by a Line Feed (‘\n’), a
Carriage Return (‘\r’), or a Carriage Return followed immediately by a Line Feed. It returns a string (i.e.
a String object) containing the contents of the line, not including any line-termination characters or null
if the end of the stream has been reached.

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 11
Java Programming : Unit 6

Example:
// Reading strings from keyboard using a BufferedReader object

import java.io.*;

class BRReadLine
{

public static void main(String args[]) throws IOException


{
try
{

// creating a BufferedReader object using System.in

BufferedReader br = new BufferedReader(new


InputStreamReader(System.in));

String str;

System.out.println("Enter lines of text:");


System.out.println("Enter 'stop' to quit.");

do {

str = br.readLine(); // Reading strings from keyboard


System.out.println(“You Entered: “+str);

} while(!str.equals("stop"));

}
catch(IOException e)
{
System.out.println("I/O Error!");
System.exit(1);
}

}
}

We now put the above code in BRReadLine.java and do the following:


$javac BRReadLine.java
$java BRReadLine

We will have the output as given below:


Enter lines of text:
Enter 'stop' to quit.

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 12
Java Programming : Unit 6
India is our Country.
You Entered: India is our Country.
New Delhi is our national capital.
You Entered: New Delhi is our national capital.
Peacock is our national bird.
You Entered: Peacock is our national bird.
Lotus is our national flower.
You Entered: Lotus is our national flower.
stop
You Entered: stop

A closer look at the much-exploited System.out.println():


In Java, System.out.println() is a statement which prints the argument passed to it on the
console, much like the printf() in C or the cout<< in C++. We use it copiously, very much like an
indivisible unit, in our Java programmes. It’s about time we dismantled it to get hold of how it actually
works.

'System' is a class in the 'java.lang' package containing several useful class fields and methods.

'out' is a static member field of the 'System' class, and is an instance of 'java.io.PrintStream' class as
shown below:

public final class System {


public static final PrintStream out;
//...
}

'println()' is a method defined in the 'java.io.PrintStream' class as shown below:

class PrintStream {
PrintStream(OutputStream os); //Constructor
public void println(String s);
//...
}
This method is overloaded to print message to output destination, which is typically a console or a file. In
addition to the job of 'print()' method, 'println()' moves the cursor to the next line after
printing the argument string. It is, therefore, used when we want the output in separate lines.

6.3 Serialization
Serialization is a mechanism of saving the state of an object by writing the object into a file through an
output byte stream. Deserialization is the reverse process where the saved state of the original object is
restored by reading the object from the file, where it was written during the process of serialization,
through an input byte stream.

Serialization lets you simply say "save this object and all of its instance variables." Actually it is a little
more interesting than that, because you can add, "... unless I've explicitly marked a variable as
transient, which means, don't include the transient variable's value as part of the object's serialized
state."

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 13
Java Programming : Unit 6

The magic of basic serialization happens with just two methods: one to serialize the object and write it to
a file using the ObjectOutputStream object, and a second to read the file using an ObjectInputStream
object and deserialize the object.

The methods are shown below:

ObjectOutputStream.writeObject() // serialize and write


ObjectInputStream.readObject() // read and deserialize

The delaration of writeObject() inside the ObjectOutputStream class:

class ObjectOutputStream{

public final void writeObject(Object obj)


throws IOException

//...

The delaration of readObject() inside the ObjectInputStream class:

class ObjectInputStream{

public final Object readObject()


throws IOException

//...

The ObjectOutputStream and ObjectInputStream classes are considered to be higher-level classes in


the java.io package, and as we learned earlier, that means that you'll wrap them around lower-level
classes, such as FileOutputStream and FileInputStream.

Here's a small samplle program that creates a (Cat) object, serializes it, and then deserializes it:

import java.io.*;
class Cat implements Serializable { } // 1
public class SerializeCat {
public static void main(String[] args) {
Cat c = new Cat(); // 2
try {
FileOutputStream fos = new FileOutputStream("testSer.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(c); // 3

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 14
Java Programming : Unit 6
oos.close();
} catch (Exception e) { e.printStackTrace(); }
try {
FileInputStream fis = new FileInputStream("testSer.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (Cat) ois.readObject(); // 4
ois.close();
} catch (Exception e) { e.printStackTrace(); }
}
}

Let's take a look at the key points in this example:

1. We declare that the Cat class implements the Serializable interface. Serializable is a marker interface;
it has no methods to implement. If we want to make a Java object serializable, its class has to implement
the Serializable interface contained in the java.io package.

2. We make a new Cat object, which as we know is serializable.

3. We serialize the Cat object referred to by ‘c’ by invoking the writeObject() method. It took a
fair amount of preparation before we could actually serialize our Cat. First, we had to create a
FileOutputStream object to write the object to a file, which is the file "testSer.ser" here. Then
we wrapped the FileOutputStream object in an ObjectOutputStream object, which is the class
containing the magic serialization method writeObject() that we need. The invocation of
oos.writeObject(c) essentially performs two tasks: it serializes the Cat object referred to by
‘c’, and then it writes this object to the "testSer.ser" file, because ‘oos’ is already connected to
"testSer.ser".

4. We then de-serialize the Cat object by invoking the readObject() method. Agein, we had to
prepare ourselves before we could actually de-serialize our Cat object. First, we had to create a
FileInputStream object to read our saved Cat object from the file "testSer.ser". Then we
wrapped the FileIntputStream object in an ObjectInputStream object, which is the class containing the
magic serialization method readObject() that we need . The invocation of
ois.readObject()essentially performs two tasks : it reads the Cat object from the
"testSer.ser" file, as ‘ois’ is already connected to "testSer.ser", de-serializes it and
then returns it. Since it returns the object in the form of the type Object, we have to cast the deserialized
object back to the type Cat.

—The End of Unit 6—

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 15
Java Programming : Unit 6

Questions:
1. What are predefined streams in Java?

2. Is it possible to print onto the console by using a user-defined object of the class
PrintStream?

3. How inputs can be received from console in Java?

4. Why we take the trouble of wrapping up the character-type stream


InputStreamReader by another character-type stream BufferedReader for receiving
characters/strings from console?

5. What is the need of serializing/de-serializing an object in Java?

6. How can an instance variable of some object be protected from getting serialized?

7. Why is it advisable to close a stream after using it in Java?

Assignments:
1. Write a programme in Java that reads data from keyboard using
BufferedInputStream and then writes it into a file using BufferedOutputStream.

2. Write a programme in Java that reads characters from keyboard using


BufferedReader and then writes it into a file using BufferedWriter.

3. Write a programme in Java that reads primitive data from a file using
DataInputStream and then prints it onto the screen.

4. Write a programme in Java that writes some primitive data into a file using
DataOutputputStream.

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 16
Java Programming : Unit 6

References:

Books:
1. The Complete Reference Java 2 by Herbert Schildt

2. Programming With Java by E. Balagurusamy

3. SCJP Sun Certified Programmer for Java 6 Study Guide by Kathy Sierra & Bert Bates

Websites:
1. https://docs.oracle.com

2. https://www.javatpoint.com

3. https://www.geeksforgeeks.org

Thank You

©Prosenjit Roy (Lecturer in Computer Sc. & Technology, APC Ray Polytechnic) Page 17

You might also like