Unit 2
Unit 2
2.0 INTRODUCTION
Input is any information that is needed by a program to complete its execution. Output
is any information that the program must convey to the user. Input and Output are
essential for applications development.
To accept input, a Java program opens a stream to a data source, such as a file or
remote socket, and reads the information serially. Whether reading data from a file or
from a socket, the concept of serially reading from, and writing to, different data
sources is the same. For that very reason, it is essential to understand the features of
top-level classes ([Link], [Link]).
In this Unit you will be working on some basics of I/O (InputOutput) in Java such as
Files creation through streams in Java code. A stream is a linear, sequential flow of
bytes of input or output data. Streams are written to the file system to create files.
Streams can also be transferred over the Internet.
In this Unit you will learn the basics of Java streams by reviewing the differences
between byte and character streams, and the various stream classes available in the
[Link] package. We will cover the standard process for standard Input (Reading from
console) and standard output (writing to console).
2.1 OBJECTIVES
After going through this Unit, you will be able to:
An InputStream represents a stream of data from which data can be read. Again, this
stream will be either directly connected to a device or else to another stream.
Input stream Input stream filter Output stream filter Output stream
[Link] package
This package provides support for basic I/O operations. When you are dealing with
the [Link] package some questions given below need to be addressed.
What is the file format: text or binary?
Do you want random access capability?
Are you dealing with objects or non-objects?
What are your sources and sinks for data?
Do you need to use filtering (You will know about it in later section of this
unit)?
For example:
If you are using binary data, such as integers or doubles, then use the
InputStream and OutputStream classes.
If you are using text data, then the Reader and Writer classes are right.
Most of the functionality available for byte streams is also provided for character
streams. The methods for character streams generally accept parameters of data type
char, while byte streams work with byte data types. The names of the methods in both
sets of classes are almost identical except for the suffix, that is, character-stream
classes end with the suffix Reader or Writer and byte-stream classes end with the
suffix InputStream and OutputStream.
For example, to read files using character streams use the [Link] class,
and for byte streams use [Link].
Unless you are writing programs to work with binary data, such as image and sound
files, use readers and writers (character streams) to read and write information for the
following reasons:
They can handle any character in the Unicode character set (while the byte
streams are limited to ISO-Latin-1 8-bit bytes).
They are easier to internationalize because they are not dependent upon a
specific character encoding.
They use buffering techniques internally and are therefore potentially much
more efficient than byte streams.
Now let us discuss byte stream classes and character stream classes one by one.
InputStream class
The InputStream class defines methods for reading bytes or arrays of bytes, marking
locations in the stream, skipping bytes of input, finding out the number of bytes
available for reading, and resetting the current position within the stream. An input
stream is automatically opened when created. The close() method can explicitly close
a stream.
Methods of InputStream class
The basic method for getting data from any InputStream object is the read()method.
public abstract int read() throws IOException: This reads a single byte from the input
stream and returns it to the stream.
26
I/O In Java
public int read(byte[] bytes) throws IOException: fills an array with bytes read from
the stream and returns the number of bytes read.
public int read(byte[] bytes, int offset, int length) throws IOException: fills an array
from a stream starting at position offset, up to the length of the bytes. This returns
either the number of bytes read or 1 for end of file.
public int available() throws IOException: the read()method always blocks when there
is no data available. To avoid blocking, the program might need to ask ahead of time
exactly how many bytes it can safely read without blocking. This method returns this
number.
public long skip(long n): the skip() method skips over n bytes ( passed as argument of
skip()method) in a stream.
public synchronized void mark (int readLimit): this method marks the current position
in the stream so it can be backed up later.
OutputStream class
The OutputStream defines methods for writing bytes or arrays of bytes to the stream.
An output stream is automatically opened when created. An Output stream can be
explicitly closed with the close() method.
public void write(byte[] bytes) throws IOException: writes the entire contents of the
bytes array to the output stream.
public void write(byte[] bytes, int offset, int length) throws IOException: writes
length, number of bytes starting at position offset from the bytes array.
27
Advanced Concepts Now let us see how Input and Output are handled in the program given below. This
program creates a file and writes a string in it, and reads the number of bytes in the
file.
// program for I/O
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class FileIOOperations {
public static void main(String args[]) throws IOException {
// Create output file [Link]
FileOutputStream outStream = new FileOutputStream("[Link]");
String s = "This program is for Testing I/O Operations";
for(int i=0;i<[Link]();++i)
[Link]([Link](i));
[Link]();
// Open [Link] for input
FileInputStream inStream = new FileInputStream("[Link]");
int inBytes = [Link]();
[Link]("[Link] has "+inBytes+" available bytes");
byte inBuf[] = new byte[inBytes];
int bytesRead = [Link](inBuf,0,inBytes);
[Link](bytesRead+" bytes were read");
[Link](" Bytes read are: "+new String(inBuf));
[Link]();
File f = new File("[Link]");
[Link]();
}
}
Output:
[Link] has 42 available bytes
42 bytes were read
Bytes read are: This program is for Testing I/O Operations.
Filtered Streams
One of the most powerful aspects of streams is that one stream can chain to the end of
another. For example, the basic input stream only provides a read()method for reading
bytes. If you want to read strings and integers, attach a special data input stream to an
input stream and have methods for reading strings, integers, and even floats.
28
I/O In Java
DataInputStream class: this implements the DataInput interface, a set of methods that
allow objects and primitive data types to be read from a stream.
LineNumberInputStream class: this is used to keep track of input line numbers.
PushbackInputStream class: this provides the capability to push data back onto the
stream that it is read from so that it can be read again.
The FilterOutputStream class provides three subclasses: BufferedOutputStream,
DataOutputStream and Printstream.
BufferedOutputStream class: this is the output class analogous to the
BufferedInputStream class. It buffers output so that output bytes can be written to
devices in larger groups.
DataOutputStream class: this implements the DataOutput interface. It provides
methods that write objects and primitive data types to streams so that they can be read
by the DataInput interface methods.
PrintStream class: this provides the familiar print() and println() methods.
You can see, in the program given below, how objects of classes FileInputStream,
FileOutputStream, BufferedInputStream, and BufferedOutputStream are used for I/O
operations.
//program
import [Link].*;
public class StreamsIODemo
{
public static void main(String args[])
{
try
{
int a = 1;
FileOutputStream fileout = new FileOutputStream("[Link]");
BufferedOutputStream buffout = new BufferedOutputStream(fileout);
while(a<=25)
{
[Link](a);
a = a+3;
}
[Link]();
FileInputStream filein = new FileInputStream("[Link]");
BufferedInputStream buffin = new BufferedInputStream(filein);
int i=0;
do
{
i=[Link]();
if (i!= -1)
[Link](" "+ i);
} while (i != -1) ;
[Link]();
}
catch (IOException e)
{
[Link]("Eror Opening a file" + e);
}
}
}
Output:
29
Advanced Concepts 1
4
7
10
13
16
19
22
25
BufferedReader
LineNumberReader
FilterReader
PushbackReader
InputStreamReader
FileReader
StringReader
Now let us see a program to understand how the read and write methods can be used.
import [Link].*;
public class ReadWriteDemo
{
public static void main(String args[]) throws Exception
{
FileReader fileread = new FileReader("[Link]");
PrintWriter printwrite = new PrintWriter([Link], true);
char c[] = new char[10];
int read = 0;
while ((read = [Link](c)) != -1)
30
I/O In Java
[Link](c, 0, read);
[Link]();
[Link]();
}
}
Output:
class StrCap
{
public static void main(String[] args)
{
StringBuffer StrB = new StringBuffer("Object Oriented Programming is possible in
Java");
String Hi = new String("This morning is very good");
[Link]("Initial Capacity of StrB is :"+[Link]());
[Link]("Initial length of StrB is :"+[Link]());
//[Link]("value displayed by the expression [Link]() is:
"+[Link]());
[Link]("value displayed by the expression [Link]() is: "+[Link]());
[Link]("value displayed by the expression [Link]() is:
"+[Link](10));
}
}
Note: Output of this program is the content of file [Link] can refer Unit 3 of
this block to see [Link] file.
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
2) Write a program for I/O operation using BufferedInputStream and
BufferedOutputStream.
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
3) Write a program using FileReader and PrintWriter classes for file handling.
…………………………………………………………………………………...
……………………………………………………………………………………
……………………………………………………………………………………
31
Advanced Concepts Access to standard input, standard output and standard error streams are provided via
public static [Link], [Link] and [Link] objects. These are usually
automatically associated with a user’s keyboard and screen.
[Link] refers to standard output stream. By default this is the console.
[Link] refers to standard input, which is the keyboard by default.
[Link] refers to standard error stream, which also is the console by default.
[Link] is an object of InputStream. [Link] and [Link] are objects of
PrintStream. These are byte streams, even though they typically are used to read and
write characters from and to the console.
The predefined PrintStreams, out, and err within system class, are useful for printing
diagnostics when debugging Java programs and applets. The standard input stream
[Link] is available, for reading inputs.
Output:
C:\JAVA\BIN>Java ConsoleInput
What is your name? Java Tutorial
Hello, Java Tutorial
The ReadWriteDemo program discussed earlier in this section 2.3.2 of this Unit is for
reading and then displaying the content of a file. This program will give you an idea
how to use FileReader and PrintWriter classes.
You may have observed that close()method is not required for objects created for
standard input and output. You should have a question in mind – whether to use
[Link] or PrintWriter? There is nothing wrong in using [Link] for sample
programs, but for real world applications, PrintWriter is easier.
Reading Files
Let’s begin with the FileReader class. As with keyboard input, it is most efficient to
work through the BufferedReader class. If input is text to be read from a file, let us
say “[Link],” it will be opened as a file input stream as follows:
BufferedReader inputFile = new BufferedReader(new FileReader("[Link]"));
The line above opens, [Link] as a FileReader object and passes it to the constructor
of the BufferedReader class. The result is a BufferedReader object, named inputFile.
To read a line of text from [Link], use the readLine() method of the BufferedReader
class.
String s = [Link]();
You can see that [Link] is not being read using input redirection. It is explicitly
opened as a file input stream. This means that the keyboard is still available for input,
so, the user can take the name of a file, instead of “hard coding”.
Once you are finished with the operations on the file, the file stream is closed as
follows:
[Link]();
Some additional file I/O services are available through Java’s File class, which
supports simple operations with filenames and paths. For example, if fileName is a
string containing the name of a file, the following code checks if the file exists and, if
so, proceeds only if the user enters "y" to continue.
File f = new File(fileName);
if ([Link]())
{
[Link]("File already exists. Overwrite (y/n)? ");
if(![Link]().toLowerCase().equals("y"))
return;
}
The program written below opens a text file called [Link] and to count the number
of lines and characters in that file.
//program
import [Link].*;
public class FileOperation
{
public static void main(String[] args) throws IOException
{
// the file must be called ‘[Link]’
String s = “[Link]”
File f = new File(s);
//check if file exists
if (![Link]())
{
[Link]("\'" + s + "\' does not exit!");
return;
}
// open disk file for input
34
I/O In Java
BufferedReader inputFile = new BufferedReader(new FileReader(s));
// read lines from the disk file, compute stats
String line;
int nLines = 0;
int nCharacters = 0;
while ((line = [Link]()) != null)
{
nLines++;
nCharacters += [Link]();
}
// output file statistics
[Link]("File statistics for \'" + s + "\'...");
[Link]("Number of lines = " + nLines);
[Link]("Number of characters = " + nCharacters);
[Link]();
}
}
Output:
File statistics for ‘[Link]’…
Number of lines = 3
Number of characters = 7
Writing Files
You can open a file output stream to which text can be written. For this, use the
FileWriter class. As always, it is best to buffer the output. The following code sets up
a buffered file writer stream named outFile to write text into a file named [Link].
PrintWriter outFile = new PrintWriter(new BufferedWriter(new FileWriter
("[Link]"));
The object outFile, is an object of PrintWriter class, just like [Link]. If a string, s,
contains some text, to be written in “[Link]”. It is written to the file as follows:
[Link](s);
When finished, the file is closed as:
[Link]();
FileWriter constructor can be used with two arguments, where the second argument is
a boolean type specifying an "append" option. For example, the expression, new
FileWriter("[Link]", true) opens “[Link]” as a file output stream. If the file
currently exists, subsequent output is appended to the file.
One more possibility is of opening an existing read-only file for writing. In this case,
the program terminates with an “access is denied” exception. This should be caught
and dealt with in the program.
import [Link].*;
class FileWriteDemo
{
public static void main(String[] args) throws IOException
{
// open keyboard for input
BufferedReader stdin = new BufferedReader(new InputStreamReader([Link]));
String s = "[Link]";
// check if output file exists
File f = new File(s);
if ([Link]())
{
[Link]("Overwrite " + s + " (y/n)? ");
if(![Link]().toLowerCase().equals("y")) 35
Advanced Concepts return;
}
// open file for output
PrintWriter outFile = new PrintWriter(new BufferedWriter(new FileWriter(s)));
[Link]("Enter some text on the keyboard...");
[Link]("(^z to terminate)");
// read from keyboard, write to file output stream
String s2;
while ((s2 = [Link]()) != null)
[Link](s2);
// close disk file
[Link]();
}
}
Output:
Enter some text on the keyboard...
(^z to terminate)
hello students ! enjoying Java Session
^Z
Open [Link] you will find
“hello students ! enjoying Java Session” is stored in it.
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
3) Write a program to read the output of a file, and display it on the console.
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
Object serialization
Serialization takes all the data attributes, writes them out as an object, and reads them
back in as an object. For an object to be saved to a disk file it needs to be converted to
a serial form. An object can be used with streams by implementing the serializable
36
I/O In Java
interface. The serialization is used to indicate that objects of that class can be saved
and retrieved in serial form. Object serialization is quite useful when you need to use
object persistence. By object persistence, the stored object continues to serve the
purpose even when no Java program is running, and stored information can be
retrieved in a program so it can resume functioning, unlike the other objects that cease
to exist when object stops running.
ObjectInput interface is used for input, which extends the DataInput interface, and
ObjectOutput interface is used for output, which extends DataOutput. You are still
going to have the methods readInt(), writeInt() and so forth. ObjectInputStream,
which implements ObjectInput, is going to read what ObjectOutputStream produces.
There are a couple of other features of a serializable class. First, there is a zero
parameter constructor. When you read the object, it needs to be able to construct and
allocate memory for an object, and it is going to fill in that memory from what it has
read from the serial stream. The static fields, or class attributes, are not saved because
they are not part of an object.
If you do not want a data attribute to be serialized, you can make it transient. That
would save on the amount of storage or transmission required to transmit an object.
The transient indicates that the variable is not part of the persistent state of the object
and will not be saved when the object is archived. Java defines two types of modifiers
Transient and Volatile.
The volatile command indicates that the variable is modified asynchronously by
concurrently running threads.
Transient Keyword
When an object that can be serialized, you have to consider whether all the instance
variables of the object will be saved or not. Sometimes, you have some objects or sub
objects which carry sensitive information like a password. If you serialize such objects
even if information (sensitive information) is private in that object it can be accessed
from outside. To control this you can turn off serialization on a field- by-field basis
using the transient keyword.
See the program, given below, to create a login object that keeps information about a
login session. In case you want to store the login data, but without the password, the
easiest way to do it is to implements Serializable and mark the password field as
transient.
//Program
import [Link].*;
import [Link].*;
public class SerialDemo implements Serializable
{
private Date date = new Date(); 37
Advanced Concepts private String username;
private transient String password;
SerialDemo(String name, String pwd)
{
username = name;
password = pwd;
}
public String toString()
{
String pwd = (password == null) ? "(n/a)" : password;
return "Logon info: \n " + "Username: " + username +
"\n Date: " + date + "\n Password: " + pwd;
}
public static void main(String[] args)
throws IOException, ClassNotFoundException
{
SerialDemo a = new SerialDemo("Java", "sun");
[Link]( "Login is = " + a);
ObjectOutputStream 0 = new ObjectOutputStream( new
FileOutputStream("[Link]"));
[Link](a);
[Link]();
// Delay:
int seconds = 10;
long t = [Link]()+ seconds * 1000;
while([Link]() < t)
;
// Now get them back:
ObjectInputStream in = new ObjectInputStream(new
FileInputStream("[Link]"));
[Link]("Recovering object at " + new Date());
a = (SerialDemo)[Link]();
[Link]( "login a = " + a);
}
}
Output:
Login is = Logon info:
Username: Java
Date: Thu Feb 03 04:06:22 GMT+05:30 2005
Password: sun
Recovering object at Thu Feb 03 04:06:32 GMT+05:30 2005
login a = Logon info:
Username: Java
Native Method is a method which is not written in Java, and is outside of the JVM in
a library. This feature is not special to Java. Most languages provide some mechanism
to call routines written in another language. In C++, you must use the extern “C”
statement to signal that the C++ compiler is making a call to C functions.
To declare a native method in Java, a method is preceded with native modifiers much
like you use the public or static modifiers, but don’t define any body for the method,
but simply place a semicolon in its place.
For example:
public native int meth();
The following class defines a variety of native methods:
public class IHaveNatives
{
native public void Native1(int x) ;
native static public long Native2();
native synchronized private float Native3( Object o ) ;
native void Native4(int[]ary) throws Exception ;
}
Native methods can be static methods, thus not requiring the creation of an object (or
instance of a class). This is often convenient when using native methods to access an
existing C-based library. Naturally, native methods can limit their visibility with the
public, private, protected, or unspecified default access.
Every other Java method modifier can be used along with native, except abstract. This
is logical, because the native modifier implies that an implementation exists, and the
abstract modifier insists that there is no implementation.
The following program is a simple demonstration of native method implementation.
class ShowMsgBox
{
public static void main(String [] args)
{ 39
Advanced Concepts ShowMsgBox app = new ShowMsgBox();
[Link]("Generated with Native Method");
}
private native void ShowMessage(String msg);
{
[Link]("MsgImpl");
}
}
……………………………………………………………………………..
……………………………………………………………………………..
……………………………………………………………………………..
…………………………………………………………………………….
…………………………………………………………………………….
……………………………………………………………………………..
……………………………………………………………………………
……………………………………………………………………………
……………………………………………………………………………..
2.9 SUMMARY
This Unit covers various methods of I/O streams binary, character and object in
Java. This Unit briefs that input and output in the Java language is organised around
the concept of streams. All input is done through subclasses of InputStream and all
output is done through subclasses of OutputStream except for RandomAccessFile. We
have seen, in this Unit, how various streams can be combined together to get the
added functionality of standard input and stream input. In this Unit you have also
learned the operations of reading from a file and writing to a file. For this purpose
objects of FileReader and FileWriter classes are used.
40