Unit 6
Unit 6
7: JAVA I/O
Contents
7.0. Aims and Objectives
7.1. I/O Fundamentals
7.2. Streams Basics
7.3.Readers
7.3.Readers and Writers
7.4. Summary
7.5. Model Examination Questions
This unit discusses file input and output streams. We will focus on stream basics, buffered
streams, reader and writer streams and finally on file managements in detail.
After you have studied this unit, you will be able to:
1
7.1. I/O FUNDAMENTALS
Input and output, I/O for short, are fundamental to any computer operating system or
programming language. Only theorists find it interesting to write programs that don't
require input or produce output. At the same time, I/O hardly qualifies as one of the more
exciting topics in computer science. It's something in the background, something you use
every day but for most developers, it's not a topic with much appeal.
There are plenty of reasons for Java programmers to find I/O interesting. Java includes a
particularly rich set of I/O classes in the core API, mostly in the java.io package. For the
most part I/O in Java is divided into two types: byte- and number-oriented I/O, which is
handled by input and output streams; and character and text I/O, which is handled by
readers and writers. Both types provide an abstraction for external data sources and
targets that allows you to read from and write to them, regardless of the exact type of the
source. You use the same methods to read from a file that you do to read from the console
or from a network connection.
Once you've defined abstractions that let you read or write without caring where your data
is coming from or where it's going to, you can do a lot of very powerful things. You can
define I/O streams that automatically compress, encrypt, and filter from one data format to
another, and more. Once you have these tools, programs can send encrypted data or write
zip files with almost no knowledge of what they're doing; cryptography or compression can
be isolated in a few lines of code. The Java language provides a simple model for input and
output (I/O). All I/O is performed by writing to and reading from streams of data. The data
may exist in a file or an array, be piped from another stream, or even come from a port on
another computer. The flexibility of this model makes it a powerful abstraction of any
required input and output.
One of the key issues regarding Java I/O is providing file support for all Java enabled
platforms. The Java file I/O classes must restrict themselves to a reasonable, "least common
denominator" of file-system functionality. Provided functionality is restricted to only those
general features that can be used on any modern platform. For example, you won't find
ways to work with OS/2's
2
"Extended attributes", or "sync" a file in UNIX. All classes referred to in this module are
located in the java.io package (unless otherwise stated.)
Data stored in a text file is represented in human-readable form. Data stored in a binary file
is represented in binary form. You cannot read binary files. They are designed to be read by
programs. For example, Java source programs are stored in text files and can be read by a
text editor, but Java classes are stored in binary files and are read by the JVM. The
advantage of binary files is that they are more efficient to process than text files.
A stream is an object that enables the flow of data between a program and some I/O device
or file.
–If the data flows into a program, then the stream is called an input stream
–If the data flows out of a program, then the stream is called an output stream
The word stream is derived from an analogy with a stream of water. An input stream is
like a siphon that sucks up water; an output stream is like a hose that sprays out water.
Siphons can be connected to hoses to move water from one place to another. Sometimes a
siphon may run out of water if it's drawing from a finite source like a bucket. On the other
hand, if the siphon is drawing water from a river, it may well provide water indefinitely. So
3
too an input stream may read from a finite source of bytes like a file or an unlimited source
of bytes like System.in. Similarly, an output stream may have a definite number of bytes to
output or an indefinite number of bytes.
Input to a Java program can come from many sources. Output can go to many different
kinds of destinations. The power of the stream metaphor and in turn the stream classes is
that the differences between these sources and destinations are abstracted away. All input
and output are simply treated as streams
The java.io package provides an extensive library of classes for dealing with input and
output. Java provides streams as a general mechanism for dealing with data I/O. Streams
implement sequential access of data. There are two kinds of streams: byte streams and
character streams.
• Character streams create text files. These are files designed to be read with a text
editor. Java automatically converts its internal Unicode characters to the local
machine representation (ASCII in our case).
• Byte streams create binary files. A binary file essentially contains the memory
image of the data. That is, it stores bits as they are in memory. Binary files are faster
to read and write because no translation need take place. Binary files, however,
cannot be read with a text editor
4
• Can be viewed, edited with text editor.
o All other files are called binary files
• Movie files, music files, Java class files
• Access requires specialized program
An input stream is an object that an application can use to read a sequence of data, and an
output stream is an object that an application can use to write a sequence of data. An input
stream acts as a source of data, and an output stream acts as a destination of data. The
following entities can act as both input and output streams:
• an array of bytes or characters
• a file and a pipe
• a network connection
Streams can be chained with filters to provide new functionality. In addition to dealing with
bytes and characters, streams are provided for input and output of Java primitive values
and objects. The java.io package also provides support for random access of files, and a
general interface to interact with the file system of the host platform.
Buffered Streams
The Byte and Character Streams so far described use unbuffered I/O
Ø This means each read or write request is handled directly by the underlying OS
Ø This can make a program much less efficient, since each such request often triggers disk
access, network activity, or some other operation that is relatively expensive.
Ø To reduce this kind of overhead, the Java platform implements buffered I/O streams.
5
Ø Buffered input streams read data from a memory area known as a buffer; the native
input API is called only when the buffer is empty.
Ø Similarly, buffered output streams write data to a buffer, and the native output API is
called only when the buffer is full
Ø A program can convert a unbuffered stream into a buffered stream using the wrapping
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));
Ø There are four buffered stream classes used to wrap unbuffered streams:
BufferedInputStream and BufferedOutputStream create buffered byte streams,
while BufferedReader and BufferedWriter create buffered character streams.
Stream classes
A stream is any input source or output destination for data. The Java API includes about
fifty classes for managing input/output streams. Objects of these classes can be instantiated
and methods exist to perform "actions" on these objects. The most basic actions are
sending data to a stream or receiving data from a stream.
6
• Reader: base class for character input streams.
3. Files and directories
• File: An object of this class is either a file or a directory.
• RandomAccessFile: provides support for random access to a file.
v Note that the classes InputStream, OutputStream, Reader, and Writer are
abstract classes.
v Reader and Writer classes handle text I/O. InputStream and OutputStream classes
handle binary I/O.
The Goal java I/O is to provide an abstraction of all types of I/O
v Memory
v File
v Directory
v Network
Java supplies Readers and Input Streams to read data; their use is similar. The following
table shows the most commonly used methods in these classes. Note that these two classes
are abstract; you won't ever create an instance of either, but they provide the base
implementation details for all other input classes.
void close() Closes the input. Always call this method when you are finished
reading what you need, as it allows the VM to release locks on the
file.
7
int read() Reads a single item from the file. In Reader, an item is a char, while
in InputStream it's a byte. The return value will either be the item or
-1 if there is no more data (end-of-file has been reached.)
int read(type[]) Attempts to fill the array with as much data as possible. If enough
data is available, the type[] (char[] for Reader, byte[] for
InputStream) will be filled with the data and the length of the array
will be returned. If there's not enough data available, it will wait
until the data is available or end-of-file is reached. In the case of end-
of-file, as much data as is available will be copied into the array and
the amount of that data will be returned. Note that the remaining
elements in the array will not be modified and should not be used!
Generally you will call this method in a loop until it does not return
the length of the array as its result.
int read(type[], int Similar to read (datum[]) but allows you to start at a specified offset
offset, int length) in the input and read a limited number of bytes.
int skip(int n) Skips past the next n bytes or characters in the file,returning the
actual number that were skipped. (If for example, end-of-file was
reached, it might skip fewer than requested).
8
void write(type[], int Similar to write(type[]), but only length units of data will be
offset, int length) written from type[], starting at the offset.
void write(int) Writes a single item (char for Writer, byte for OutputStream) to
the file.
void write(String) Writes the contents of a java.lang.String to the file.
(Writer only!)
void write(String, int Writes the substring starting at offset and length characters long to
offset, int length) the file.
(Writer only!)
• class(File) - create an input or output file based on the abstract path name passed in
• class(String)- create an input or output file based on the String path name
• class(FileDescriptor)- create an input or output file based on a FileDescriptor (you
generally won't use this and this class will not discuss it)
• class(String, boolean)- [for output classes only] create an input or output file
based on the path name passed in, and if the boolean parameter is true, append to
the file rather than overwrite it.
9
How to do I/O
Import java.io.*;
1. Open the stream
2. Use the stream (read, write, or both)
3. Close the stream
File Management
The streams System.in and System.out are convenient for examples, but in real life, you'll
more commonly attach streams to data sources like files and network connections. You'll
use the java.io.FileInputStream and java.io.FileOutputStream classes, which are concrete
subclasses of java.io.InputStream and java.io.OutputStream, to read and write files.
FileInputStream and FileOutputStream provide input and output streams that let you read
and write files. We'll discuss these classes in detail; they provide the standard methods for
reading and writing data. What they don't provide is a mechanism for file specific
operations, like finding out whether a file is readable or writable.
Reading Files
java.io.FileInputStream is a concrete subclass of java.io.InputStream. It provides an input
stream connected to a particular file.
public class FileInputStream extends InputStream
FileInputStream has all the usual methods of input streams, such as read(), available(),
skip(), and close(), which are used exactly as they are for any other input stream.
o public native int read() throws IOException
o public int read(byte[] data) throws IOException
o public int read(byte[] data, int offset, int length) throws IOException
o public native long skip(long n) throws IOException
o public native int available() throws IOException
o public native void close() throws IOException
10
These methods are all implemented in native code, except for the two multibyteread()
methods. These, however, just pass their arguments on to a private native method called
readBytes(), so effectively all these methods are implemented with native code.
There are three FileInputStream() constructors, which differ only in how the file to be read
is specified:
publicFileInputStream(String fileName) throws IOException
publicFileInputStream(File file) throws FileNotFoundException
publicFileInputStream(FileDescriptorfdObj)
Exercise: To read a file, just pass the name of the file into the FileInputStream()
constructor. Then use the read() method as normal. For example, the following code
fragment reads the file README.TXT, then prints it on System.out:
try
{
FileInputStream fis = new FileInputStream("README.TXT");
int n;
while ((n = fis.available()) > 0) {
byte[] b = new byte[n];
int result = fis.read(b);
if (result == -1)
break;
String s = new String(b);
System.out.print(s);
} // End while
} // End try
catch (IOException e) {System.err.println(e);}
System.out.println();
Java looks for files in the current working directory. Generally, this is the directory you
were in when you typed java program_name to start running the program. You can open a
file in a different directory by passing a full or relative path to the file from the current
11
working directory. For example, to read the file /student/Files no matter which directory is
current, you can do this:
FileInputStream fis = new FileInputStream("/student/Files ");
Notice that this code depends on Unix-style pathnames. It is not guaranteed to work on
Windows or the Mac, though it might; some runtime environments like Apple's Macintosh
Runtime for Java include extra code to translate from Unix-style filenames to the native
style. If the file you're trying to read does not exist when the FileInputStream object is
constructed, a FileNotFoundException (a subclass of java.io.IOException) is thrown. If for
some other reason a file cannot be read—for example, the current process does not have
read permission for the file—some other kind of IOException is thrown.
Writing Files
The java.io.FileOutputStream class is a concrete subclass of java.io.OutputStream that
provides output streams connected to files.
public class FileOutputStream extends OutputStream
This class has all the usual methods of output streams, such as write(), flush(), and close(),
which are used exactly as they are for any other output stream.
These are all implemented in native code except for the two multibyte write () methods.
These, however, just pass their arguments on to a private native method called
writeBytes(), so effectively all these methods are implemented with native code.
There are three main FileOutputStream() constructors, differing primarily in how the file is
specified:
publicFileOutputStream(String filename) throws IOException
publicFileOutputStream(File file) throws IOException
publicFileOutputStream(FileDescriptorfd)
12
The first constructor uses a string containing the name of the file; the second constructor
uses a java.io.File object; the third constructor uses a java.io.FileDescriptor object. To write
data to a file, just pass the name of the file to the FileOutputStream() constructor, then use
the write() methods as normal. If the file does not exist, all three constructors will create it.
If the file does exist, any data inside it will be overwritten. A fourth constructor also lets
you specify whether the file's contents should be erased before data is written into it
(append == false) or whether data is to be tacked onto the end of the file (append == true).
The other three constructors simply overwrite the file; they do not provide an option to
append data to the file.
Java looks for files in the current working directory. You can write to a file in a different
directory by passing a full or relative path to the file from the current working directory.
For example, to append data to the \Windows\java\javalog.txt file no matter which
directory is current, you would do this:
FileOutputStreamfout = new FileOutputStream("/Windows/java/javalog.txt", true);
Although Windows uses a backslash as the directory separator, Java still expects you to use
a forward slash as in Unix.
7.4. SUMMARY
Java I/O (Input and Output) is used to process the input and produce the output. Java uses
the concept of a stream to make I/O operation fast. The java.io package contains all the
13
classes required for input and output operations. We can perform file handling in Java by
Java I/O API.
A stream is a sequence of data. In Java, a stream is composed of bytes. It's called a stream
because it is like a stream of water that continues to flow. In Java, 3 streams are created for
us automatically. All these streams are attached with the console.
The java.io package contains nearly every class you might ever need to perform input and
output (I/O) in Java. All these streams represent an input source and an output
destination. The stream in the java.io package supports many data such as primitives,
object, localized characters, etc.
Java Byte streams are used to perform input and output of 8-bit bytes, whereas
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. Though internally FileReader uses FileInputStream and
FileWriter uses FileOutputStream but here the major difference is that FileReader reads
two bytes at a time and FileWriter writes two bytes at a time.
All the programming languages provide support for standard I/O where the user's
program can take input from a keyboard and then produce an output on the computer
screen. If you are aware of C or C++ programming languages, then you must be aware of
three standard devices STDIN, STDOUT and STDERR. Similarly, Java provides the
following three standard streams:
• Standard Input − This is used to feed the data to user's program and usually a
keyboard is used as standard input stream and represented as System.in.
14
• Standard Output − This is used to output the data produced by the user's program
and usually a computer screen is used for standard output stream and represented
as System.out.
• Standard Error − This is used to output the error data produced by the user's
program and usually a computer screen is used for standard error stream and
represented as System.err.
I: True/False questions
1. A stream is an object that enables the flow of data between a program and some
I/O device.
2. FileOutputStream has all the usual methods of input streams, such as read(),
available(), skip(), and close().
3. Buffered input streams read data from a memory area known as a buffer.
4. Binary files are faster to read and write because no translation need take place.
II: Short Answer Questions
15