Chapter 13 (File Input/Output

advertisement
Input / Output
Chapter 13

We use files all the time
Programs are files
 Documents are files


We want them to be “permanent”
To last beyond execution of a program
 We want to access and use them again
 A file can be input into or output from a
program


Open file



Close file



Create object
Associate stream of bytes with it
Make it no longer available to application
Should always close every file you open
Stream



Bytes flowing into program from input device
Bytes flow out of application to output device
Most streams flow in only one direction

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


Input streams can flow from the keyboard
or from a file

System.in is an input stream that connects to
the keyboard
Scanner keyboard = new Scanner(System.in);

Output streams can flow to a screen or to a
file

System.out is an output stream that connects
to the screen
System.out.println("Output stream");

Files that are designed to be read by human
beings, and that can be read or written with
an editor are called text files
Text files can also be called ASCII files because
the data they contain uses an ASCII encoding
scheme
 An advantage of text files is that the are usually
the same on all computers, so that they can
move from one computer to another


Files that are designed to be read by
programs and that consist of a sequence of
binary digits are called binary files
Binary files are designed to be read on the same
type of computer and with the same
programming language as the computer that
created the file
 An advantage of binary files is that they are
more efficient to process than text files


File class

–

Gather file information
java.io package
Open a file
File someData = new File("Data.txt");
File someData = new
File("C:\\MyDocuments\\Data.txt");
import java.io.*;
public class FileOpen {
public static void main(String[ ] args) {
File myFile = new File("Data.txt" );
if(myFile.exists( )) {
System.out.println(myFile.getName( ) + " exists");
System.out.println(" The file is " + myFile.length( ) +
" bytes long");
if (myFile.canRead( ))
System.out.println("OK to read");
else
System.out.println("not OK to read");
}
else
System.out.println("File does not exist");
}
}

The class Scanner can be used for reading from
the keyboard as well as reading from a text file

Simply replace the argument System.in (to the
Scanner constructor) with a suitable stream that is
connected to the text file
Scanner SomeData = new Scanner(new File("Data.txt"));

Methods of the Scanner class for reading input
behave the same whether reading from the
keyboard or reading from a text file

For example, the nextInt and nextLine methods

Write code to read data from a file:

Imagine you are reading data from keyboard


Put usual Scanner and next codes in program
Add some extra items

Add import declaration: import java.io.*





Use java.io.File and java.io.IOException
Type throws IOException into method header
Type new File(“ “) into your call to new Scanner
Type file name inside quotation marks
Use
next, nextLine, nextInt, etc
import java.util.Scanner;
import java.io.*
public class FileOpen {
public static void main(String[ ] args) throws IOException{
Scanner input = new Scanner(new File("Data.txt" ));
String line1 = input.nextLine( );
String line2 = input.nextLine( );
System.out.println(line1);
System.out.println(line2);
}
}


How do we save data to a text file?
We can produce an object of the class
PrintWriter that is connected to the file
FileName




The process of connecting a stream to a file is called
opening the file
If the file already exists, then doing this causes the old
contents to be lost
If the file does not exist, then a new, empty file named
FileName is created
After doing this, the methods print and
println can be used to write to the file

PrintWriter

Create an object using PrintWriter
PrintWriter output = new PrintWriter("Data.txt"));
We can now print to the text file using print or
println
 Instead of System.out, we will use our new object

output.println("This goes to our new file“);

When a program is finished writing to a file, it
should always close the stream connected to that
file
outputStreamName.close();


This allows the system to release any resources used to
connect the stream to the file
If the program does not close the file before the
program ends, Java will close it automatically, but it is
safest to close it explicitly

Output streams connected to files are usually
buffered



Rather than physically writing to the file as soon as
possible, the data is saved in a temporary location
(buffer)
When enough data accumulates, or when the method
flush is invoked, the buffered data is written to the file
all at once
This is more efficient, since physical writes to a file can
be slow

The method close invokes the method flush,
thus insuring that all the data is written to the file



If a program relies on Java to close the file, and the
program terminates abnormally, then any output that
was buffered may not get written to the file
Also, if a program writes to a file and later reopens it to
read from the same file, it will have to be closed first
anyway
The sooner a file is closed after writing to it, the less
likely it is that there will be a problem
import java.io.*
public class FileOutput {
public static void main(String[ ] args) throws IOException{
PrintWriter listOut = new PrintWriter("List.txt");
listOut.println("This is our printout");
listOut.close( );
}
}


Data stored in a text file are represented in
human-readable form.
Data stored in a binary file are represented in
binary form.
You cannot read binary files.
 Binary files are designed to be read by programs.
 The advantage of binary files is that they are
more efficient to process than text files.
 We can use Streams to handle binary files


InputStream and OutputStream

Abstract classes that contain methods for
performing input and output



One of the ways to improve the performance
of a program that reads input streams is to
buffer the input
Buffering is the process of saving data in
memory for use later when a program needs
it
When a Java program needs data from a
buffered input stream, it looks in the buffer
first, which is faster than reading from a
source such as a file

The class BufferedReader is a stream class that can be
used to read from a text file


An object of the class BufferedReader has the methods read
and readLine
A program using BufferedReader, like one using
PrintWriter, will start with a set of import statements:
import
import
import
import
java.io.BufferedReader;
java.io.FileReader;
java.io.FileNotFoundException;
java.io.IOException;


This stream class uses FileReader to convert the
file name to an object that can be used as an
argument
A stream of the class BufferedReader is created
and connected to a text file as follows:
BufferedReader someData = new
BufferedReader(new FileReader("Data.txt"));

This opens the file for reading

After these statements, the methods read and
readLine can be used to read from the file



The readLine method is the same method used to
read from the keyboard, but in this case it would read
from a file
The read method reads a single character, and returns
a value (of type int) that corresponds to the character
read
Since the read method does not return the character
itself, a type cast must be used:
char next = (char)(someData.read());

Unlike the Scanner class, the class
BufferedReader has no methods to read a number
from a text file



Instead, a number must be read in as a string, and then
converted to a value of the appropriate numeric type using
one of the wrapper classes
To read in a single number on a line by itself, first use the
method readLine, and then use Integer.parseInt,
Double.parseDouble, etc. to convert the string into a
number
If there are multiple numbers on a line, StringTokenizer
can be used to decompose the string into tokens, and then
the tokens can be converted as described above
import java.io.*
public class FileOpen {
public static void main(String[ ] args) throws IOException{
BufferedReader input = new BufferedReader(new
FileReader("Data.txt" ));
String line1 = input.readLine( );
String line2 = input.readLine( );
input.close( );
System.out.println(line1);
System.out.println(line2);
}
}

Objects can also be input and output from a
binary file
Use the writeObject method of the class
ObjectOutputStream to write an object to a
binary file
 Use the readObject method of the class
ObjectInputStream to read an object from a
binary file


The class ObjectInputStream is a stream class
that can be used to read from a binary file


An object of this class has methods to read strings,
values of primitive types, and objects from a binary file
A program using ObjectInputStream needs to
import several classes from package java.io:
import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.IOException;

An ObjectInputStream object is created and
connected to a binary file as follows:
ObjectInputStream someData = new ObjectInputStream(
new FileInputStream(("Data.txt"));



The constructor for FileInputStream may throw a
FileNotFoundException
The constructor for ObjectInputStream may throw
an IOException
Each of these must be handled

After opening the file, ObjectInputStream
methods can be used to read to the file




Methods used to input primitive values include
readInt, readDouble, readChar, and
readBoolean
The method readUTF is used to input values of type
String
If the file contains multiple types, each item type
must be read in exactly the same order it was
written to the file
The stream should be closed after reading


Reading and writing strings and characters may
need to be converted to binary components. The
computer can handle Unicode which consists of
two bytes:
UTF-8 is a coding scheme that allows systems to
operate with both ASCII and Unicode efficiently.



Most operating systems use ASCII.
Java uses Unicode.
The ASCII character set is a subset of the Unicode
character set.

To construct a ObjectOutputStream, use the
following constructors:
FileOutputStream ("Data.txt")
FileOutputStream ("Data.txt", boolean append)


If the file does not exist, a new file would be created.
If the file already exists, the first constructor would
delete the current contents in the file.
To retain the current content and append new data
into the file, use the last constructor by passing true
to the append parameter.

Not all objects can be written to an output
stream. Objects that can be written to an
object stream is said to be Serializable
The Serializable interface is easy to use
and requires no knowledge of interfaces
 A class that implements the Serializable
interface is said to be a serializable class


In order to make a class serializable, simply
add implements Serializable to the
heading of the class definition
public class SomeClass implements Serializable

When a serializable class has instance
variables of a class type, then all those classes
must be serializable also

A class is not serializable unless the classes for all
instance variables are also serializable for all levels
of instance variables within classes


The streams for sequential access to files
are the ones most commonly used for file
access in Java
However, some applications require very
rapid access to records in very large
databases

These applications need to have random access
to particular parts of a file


The stream class RandomAccessFile, which is
in the java.io package, provides both read and
write random access to a file in Java
A random access file consists of a sequence of
numbered bytes



There is a kind of marker called the file pointer that is
always positioned at one of the bytes
All reads and writes take place starting at the file
pointer location
The file pointer can be moved to a new location with the
method seek

Although a random access file is byte oriented,
there are methods that allow for reading or
writing values of the primitive types as well as
string values to/from a random access file

These include readInt, readDouble, and readUTF
for input, and writeInt, writeDouble, and
writeUTF for output


The constructor for RandomAccessFile takes
either a string file name or an object of the class
File as its first argument
The second argument must be one of four strings:


"rw", meaning the code can both read and write to the
file after it is open
"r", meaning the code can read from the file, but not
write to it
RandomAccess someData = new RandomAccess(
"Data.txt", "rw"));

You are sitting behind the desk at the Java Hotel.
Here comes a party of 4 and they would like a
room. You need to check to see if a room is vacant.
If one is, you then need to modify the guest list
when you assign the room

First let’s create the Guest list file
import java.io.*;
class GuestList {
public static void main(String[ ] args) throws IOException{
int guests [] = {1, 4, 2, 0, 0, 2, 4, 1, 0, 1};
int roomNum;
PrintStream listOut = new PrintStream("GuestList.txt");
for (roomNum = 0; roomNum < 10; roomNum++){
listOut.print(guests[roomNum]);
listOut.print(" ");
}
listOut.close( );
}
}

Now we need to create the code to check for
an available room
We need to open and read the file
 We need to verify if a room is unoccupied
 We need to ask the how many in your party
 We need to update the GuestList file

import java.util.Scanner;
import java.io.*;
class FindVacancy {
public static void main(String[ ] args) throws IOException{
int guests [ ] = new int[10];
int roomNum;
Scanner input = new Scanner(System.in);
Scanner file = new Scanner(new File("GuestList.txt"));
for (roomNum = 0; roomNum < 10; roomNum++)
guests[roomNum] = file.nextInt();
// continued on next slide
roomNum = 0;
while (roomNum < 10 && guests[roomNum] != 0)
roomNum++;
if (roomNum == 10)
System.out.println("Sorry, no vacancy");
else {
System.out.println("How many people for room " + roomNum + " ?");
guests[roomNum] = input.nextInt( );
PrintStream listOut = new PrintStream("GuestList.txt");
for (roomNum = 0; roomNum < 10; roomNum++){
listOut.print(guests[roomNum]);
listOut.print(" ");
}
}
}
}
Download