Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
1
Input output for a file tutorial
Streams and File I/O
In this tutorial we study the following concepts:
Text File I/O
Techniques for a file: Class File
Binary File I/O
File Objects and File Name
Note: For question 4 of the midterm you only need to look at the sections 2.2 and 2.3. I
do not think you need java class: StringTokenizer. But I just added a small section about
it to the end of this tutorial.
So far we learned keyboard/screen I/O. It is time to learn File I/O.
1 An Overview of stream and file I/O
A stream is an object that either outputs data or inputs data. The Java System.out is a
stream object that outputs data on the screen.
As our program gets bigger and bigger we may need to enter a lot of data every time we
run our program. We also may have a lot of data as the output of the program. It is not
practical to enter a sizable input from the keyboard. Therefore, we save the data in a file
and let our program to input from this file. Similarly, it is not practical to look at a sizable
output. Moreover, we may need to save the output for further study. Therefore, we let our
program to output to a file.
We have two kinds of I/O files: Text files and binary files. A text file is readable and
understandable by human, but a binary file is not. The size of a text file is bigger than the
size of a binary file. We can write arrays without using a loop into a binary file. We can
also write objects to a binary file.
2 Text-File I/O
In this section we learn how to input from a text file and how to output to a text file. We
first look at output instructions for a text file.
2.1 Text-File Output with PrintWriter class.
To be able to write to a file we need the Java class PrintWriter. This class is in JDK
java.io, therefore we need to import it . Another class that we need is : FileOutputStream.
This class also is in java.io. A file output stream is an output stream for writing data to a
File.
2
Example 1. The following program to write an integer, a floating point number, a
Boolean value and a string into a text file.
import java. io. PrintWriter;
import java. io. FileNotFoundException;
public class Main {
public static void main( String[] args) {
PrintWriter out = null;
try {
out = new PrintWriter("out.txt");
} catch( FileNotFoundException e) {
System. out. println("Error: opening the file out.txt");
System. exit( 0);
}
out.println(-12);
out.println(25.5);
out.println(true);
out.println("John Doe.");
//Note that we also can write:
out.println(-12+"\n"+ 25.5 + "\n" + true + "\n" + "John Doe.");
out.close();
}
}
The content of the file out.txt would be:
-12
25.5
true
John Doe.
-12
25.5
true
John Doe.
Description:
First we need to declare a variable that refers to and object of class PrintWriter. This class
has several constructors. One of them needs the name of the output file on the hard drive
(or other storages):
out = new PrintWriter("out.txt")
This instruction connects the variable: out to the actual name of the file: out.txt on the
hard disk. We need to include this instruction in a try-catch block because we may not
have space on the hard disk (or the storage is not writeable). In this case the program
cannot create a file on the disk. The name of the variable: out is optional. After
establishing this connection we use all the print and println that we use for standard
output. The standard output is the display screen. At the end we must close the file. In
3
reality when our program wants to write data to a file, it first writes it to the output buffer
(An array of characters). Then the I/O system of the computer writes it to the file. If we
do not close, or flush the data, the system won’t write the last part of the data into file.
Exercise 1: Change the program in example 1 such that the program asks the user to
enter the name of the output file. The program then must create a file with this name on
the hard drive.
Appending to a text file
Every time we run the program in example 1 it removes the file out.txt from the hard
drive, creates an empty file with this name, and outputs data to that name. To be able to
append the data we need to use another constructor of the class PrintWriter.
Example 2: The following program appends data to a file provided we run it more than
one time.
import java.io.FileOutputStream;
import java. io. PrintWriter;
import java. io. FileNotFoundException;
public class Main {
public static void main( String[] args) {
PrintWriter out = null;
try {
out = new PrintWriter( new FileOutputStream("out.txt", true));
} catch( FileNotFoundException e) {
System. out. println("Error: opening the file out.txt");
System. exit(0);
}
out.println("Hell World");
out.close();
}
}
Description:
This constructor of the class PrintWriter accepts an object of the type of the java class:
FileOutputStam. This class in turn has a constructor that needs the name of the file on
the hard disk and/or Boolean value. If the Boolean value is true the program appends to
the file. If it is false or we do not write it the program creates a new file. In summary:
a) With: new PrintWriter( new FileOutputStream("out.txt", true)). The
program appends:
b) With:
new PrintWriter( new FileOutputStream("out.txt", false));
Or:
new PrintWriter( new FileOutputStream("out.txt"));
The program deletes the file (if any) and creates a new file.
4
2.2 Reading from a Text-File
We now learn how to read from a text file.
Example 3: The following program reads two lines from a file named: in.txt and display
them on the screen:
import java. util. Scanner;
import java. io. File;
public class Main {
public static void main( String[] args) {
Scanner inputStream = null;
try{
inputStream = new Scanner( new File("in.txt"));
}catch(Exception e){
System.out.println("Error: " + e.getMessage());
System.exit(0);
}
String line = inputStream. nextLine();
System. out. println(line);
line = inputStream. nextLine();
System. out.println(line);
inputStream.close();
}
}
First Sample Output:
Error: in.txt (The system cannot find the file specified)
In this sample screen output we did not created the input file. Therefore when instruction:
inputStream = new Scanner( new File("in.txt"));
Gets executed and an exception occurs and the control of execution jumps to the catchblock and prints a message from the parameter: e.
Note that the java class Scanner has a different type of argument for its constructor. The
segment: System.in was for reading from the standard input (i.e. the keyboard). In the
above case the constructor has an object of the type java class: File. This class accepts a
file name for its constructor. If this file name does not exist on the hard disk the execution
of the above statement throws an exception.
Second Sample Output:
Hello
Have a nice day
5
In this sample we have a file on the disk with the name in.txt and the file has two lines (or
more). The file contains three lines:
Hello
Have a nice day
I may not show on the output
Note that the program only reads the first two lines.
We may have a situation that we do not have enough data value in an input file. Let us
take care of this situation.
Exercise: Make the file read protected and try the above program.
Example 4: The following program reads five lines from an input file:
import java.util.Scanner;
import java.io.File;
public class Main {
public static void main( String[] args) {
Scanner inputStream = null;
try{
inputStream = new Scanner( new File("in.txt"));
}catch(Exception e){
System.out.println("Error: " + e.getMessage());
inputStream.close();
System.exit(0);
}
for(int i = 1; i <= 5; i++){
String line = inputStream. nextLine();
System.out.println(line);
}
inputStream.close();
}
}
Sample Output:
Hello
Have a nice day
I may not show on the output !
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at Main.main(Main.java:14)
The catch block is for the time the file does not exist. As we see we need to add the
exception: NoSuchElementException for the case we do not have enough data in the file.
Example 5: The following program is the same as the one in example 4 but our program
controls the exception process rather than Java Virtual Machine (JVM):
6
import
import
import
import
java.util.NoSuchElementException;
java. util. Scanner;
java. io. File;
java.io.FileNotFoundException;
public class Main {
public static void main( String[] args) {
Scanner inputStream = null;
try{
inputStream = new Scanner( new File("in.txt"));
for(int i = 1; i <= 5; i++){
String line = inputStream. nextLine();
System. out. println(line);
}
}catch(FileNotFoundException e){
System.out.println("Error: " + e.getMessage());
}
catch(NoSuchElementException e){
System.out.println("Error: " + e.getMessage());
}
inputStream.close();
System.out.println("The end of the program.");
}
}
Sample Output:
Hello
Have a nice day
I may not showing on the output !
Error: No line found
The end of the program.
Description:
In the fourth iteration of the for-loop the program tries to read the fourth line from the
input file. But no more line exist and the program throws an exception which is caught by
the second catch block. Unlike example 4 the execution does not terminates and the
control of execution continues the execution of the rest of the program.
Exercise 2: Write a program to read integers from an input file and displays the average
of those numbers.
Note: The file can have any numbers of integers (including no number in the file).
Exercise 3: The following program reads an integer for n and then n decimal numbers
from the keyboard. The program sorts the numbers and displays them on the screen.
Change the program to read all numbers from an input file and store the sorted numbers
into an output file.
Restrictions: The program should ask the user for the name of the input and output file.
7
import java.util.*;
public class Main {
public static void main( String[] args) {
Scanner keyboard = new Scanner( System.in);
System.out.print("How many numbers? ");
int n = keyboard.nextInt();
float a[] = new float[n];
System.out.println("Enter " + n + " numbers:");
for(int i = 0; i < a.length; i++)
a[i] = keyboard.nextFloat();
sort(a);
System.out.println("Sorted list:");
for(int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
private static void sort(float[] a){
float smaller;
int index;
for(int i = 0; i < a.length; i++){
index = i;
smaller = a[i];
for(int j = i + 1; j < a.length; j++)
if(smaller > a[j]){
smaller = a[j];
index = j;
}
a[index] = a[i];
a[i] = smaller;
}
}
}
2.3 Techniques for any file
If a file is in a separate folder than our project folder we need to give the complete path.
Suppose in example 5 the file is in a separate folder named: Temp and this folder is in the
C drive. The path for this file is:
C:\Temp
We give this path in either two ways:
a) inputStream = new Scanner( new File("C:/Temp/in.txt"));
b) inputStream = new Scanner( new File("C:\\Temp\\in.txt"));
In the second format since backslash is used for escape characters such az \n, \t we need
to use a double-backslash.
If the file name is in variable such as: fileName we need to write:
8
inputStream = new Scanner( new File("C:/Temp/" + fileName));
The java class File has a number of methods. Some of them are:
In the following program we use these methods and more:
Example 6: The following program tests the above methods. You need to create four text
files.
public class Main {
public static void main( String[] args) {
File f1 = new File("file1.txt");
File f2 = new File("file2.txt");
File f3 = new File("file3.txt");
File f4 = new File("file4.txt");
//The following if-else statement does not work in Windows. It works in LINUX/UNIX
if(f1.canRead())
System.out.println("File file1.txt is readable.");
else
System.out.println("File file1.txt is read protected.");
if(f2.canWrite())
System.out.println("File file2.txt is writeable.");
else
System.out.println("File file2.txt is write protected");
if(f3.delete())
System.out.println("File file3.txt is now deleted");
9
else
System.out.println("File file3.txt does not exist to delete.");
if(f3.exists())
System.out.println("File file3.txt exists");
else
System.out.println("File file3.txt does not exists");
System.out.println("There is a file on the disk with the name: " + f4.getName());
System.out.println("Its path is: " + f4.getPath());
System.out.println("Its length which is the number of characters is: " +
f4.length());
}
}
Description: We change the attributes of a file on the disk by right clicking on it and
changing its properties.
3 Basic binary files
Since a binary file stores data in the same format as computer (i.e in binary numbers), it
is a more efficient file for processing. Two Java classes handle binary file I/O, the
ObjectOutputStream and the ObjectInputStream. The output methods are writeInt,
writeDouble, writeChar, writeBoolean, and writeUTF (for string), etc.Binary files are
more compact than text files.
Example 7: The following program creates binary file writes some integer into the file.
import
import
import
import
java.
java.
java.
java.
io.
io.
io.
io.
FileOutputStream;
ObjectOutputStream;
FileNotFoundException;
IOException; import java. util. Scanner;
public class Main {
public static void main( String[] args) {
String fileName = "numbers.dat";
try {
ObjectOutputStream outputStream = new ObjectOutputStream(
new FileOutputStream(fileName));
Scanner keyboard = new Scanner( System. in);
System. out. println("Enter nonnegative integers.");
System. out. println("Place a negative number at the end.");
int anInteger;
do {
anInteger = keyboard. nextInt();
outputStream.writeInt(anInteger);
} while ( anInteger >= 0);
System. out. println("Numbers and sentinel value");
System. out. println("written to the file " + fileName);
outputStream. close();
} catch( FileNotFoundException e) {
System. out. println("Problem opening the file " + fileName);
} catch( IOException e) {
System. out. println("Problem with output to file " + fileName);
10
}
}
}
Sample Output
Enter nonnegative integers.
Place a negative number at the end.
1 2 3 -1
Numbers and sentinel value
written to the file numbers.dat
Description:
The instruction:
ObjectOutputStream outputStream = new ObjectOutputStream(
new FileOutputStream(fileName))
Creates an output stream. The constructor of the class: ObjectOutputStream needs an
object of the type: FileOutputStream. The constructor of this class in turn needs a file
name. The following loop repeatedly reads an integer from the keyboard and writes to the
binary file:
do {
anInteger = keyboard. nextInt();
outputStream.writeInt(anInteger);
} while ( anInteger >= 0);
Since a binary file is byte oriented we basically should say how many bytes we like to
write to or read from the file. In the above loop the instruction:
outputStream.writeInt(anInteger). writes data of the size of an integer to the file.
The size of an integer is 8 bytes. To clarify this more let us change this instruction to:
outputStream.writeChar(anInteger);
In this case only part of these 8 bytes (i.e. 2 bytes) will be written.
The class outputStream has a number of methods. Some of them are:
11
12
Example 8: The following program practices all the above “write” methods:
import java.io.*;
public class Main{
public static void main(String[] args) {
try{
ObjectOutputStream st = new ObjectOutputStream(
new FileOutputStream("out.dat"));
st.writeInt(-5);
st.writeDouble(12.5);
st.writeChar('A');
st.writeBoolean(true);
st.writeUTF("John Doe.");
st.close();
}catch(IOException e){
System.out.println(
"Error: Cannot create the file.");
System.exit(0);
}
}
}
Description: We are writing all types of data into the file: out.dat.
The program does not have any instruction to display data. In order to find whether we
have written all of these data into this file we need to read from the file and display them
on the screen.
We must read the same way we wrote. The class:ObjectInputStream is used to read from
a binary file and has similar methods. Some of them are:
13
14
Example 9: The following program reads data from the binary file out.dat in the same
order and same size and displays on the screen.
import java.io.*;
public class Main{
public static void main(String[] args) {
try{
ObjectInputStream st = new ObjectInputStream(
new FileInputStream("out.dat"));
int i = st.readInt();
double d = st.readDouble();
char c = st.readChar();
boolean b = st.readBoolean();
String s = st.readUTF();
st.close();
System.out.println(i+"\n"+d+"\n"+ c + "\n" + b + "\n" + s);
}catch(IOException e){
//or Exception
System.out.println("Error: Make sure the file exists in the " +
"current folder.");
}
}
}
Sample output:
-5
12.5
A
true
John Doe.
Description: Note that any data value and its size that has written to the file in example 8
are read from the file with the same size and order.
Exercise 4: Change the above program to read data in the following order:
char c = st.readChar();
String s = st.readUTF();
boolean b = st.readBoolean();
char c = st.readChar();
double d = st.readDouble();
int i = st.readInt();
Exercise 5: The following program generates a random positive integer for n and
generates n floating number and saves them in a file named: in.dat. The program displays
the biggest, smallest numbers and the average of all n floating numbers.
Change the program to read from the binary file binaryIn.dat and displays the biggest,
smallest numbers and the average of all n floating numbers.
import java. util. Scanner;
import java.io.File;
15
public class Main {
public static void main( String[] args) {
Scanner inputStream = null;
int biggest= 0;
int smallest = 0;
int sum = 0;
int count = 0;
try{
inputStream = new Scanner( new File("in.txt"));
biggest = inputStream. nextInt();
count++;
smallest = biggest;
sum = biggest;
while(true){
int x = inputStream.nextInt();
count++;
sum = sum + x;
if(x > biggest)
biggest = x;
if(x < smallest)
smallest = x;
}
}catch(Exception e){
System. out. println("The biggest number is: " +
biggest);
System. out. println("The biggest number is: " +
smallest);
System. out. println("The sum is: " + sum);
System. out. println("The average is: " +
(double)sum/count);
}
inputStream.close();
}
}
5 Binary Files I/O with Objects and Arrays
The binary file I/O can handle records (i.e. more than one item at a time). A record is
object of a class. To use this class for binary I/O files we must make the class
serializable. The serialization interface has no methods. This interface is used to make a
class serializable. By making a class serializable we can write the objects to a binary file.
To write a record (object) to the file we use Java method writeObject. To read a record
from the file we use Java method readObject.
Example 10: The following program writes a record of a person into a binary file and
then read from the binary file and display the record on the screen. The record has a
name, age, and ss#.
import java.io.*;
public class Person implements Serializable{
static final long serialVersionUID = 12;
private String name;
16
private int age;
private String ss;
public Person(String name, int age, String ss){
this.name = name;
this.age = age;
this.ss = ss;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String getSS(){
return ss;
}
}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
import java.io.*;
public class Main{
public static void main(String[] args) {
output();
input();
}
public static void output(){
Person p = new Person("John Doe", 45, "123456789");
try{
ObjectOutputStream st = new ObjectOutputStream(
new FileOutputStream("out.dat"));
st.writeObject(p);
st.close();
}catch(Exception e){
System.out.println("Error 1: " + e.getMessage());
System.exit(0);
}
}
public static void input(){
try{
ObjectInputStream st = new ObjectInputStream(
new FileInputStream("out.dat"));
Person p = (Person) st.readObject();
System.out.println(p.getName() + ", " + p.getAge() + ", " +
p.getSS());
}catch(Exception e){
System.out.println("Error 2: " + e.getMessage());
System.exit(0);
}
}
17
}
Sample output:
John Doe, 45, 123456789
Description:
The method: output()creates an object of the type: Person, passing John Doe, 45, and
123456789 as a name, an age, and an ss# to the constructor. The statement:
st.writeObject(p)writes this object to a binary file.
The method: input()reads a number of bytes from the binary file and display them. The
number of the bytes is the size of the instant variables name, age, and ss in the class
Person. Note that it is the casting in: (Person) st.readObject() that tells the
control of execution how many bytes should be read from the file.
Array Objects in Binary Files
We now extend the above program to write an array into a binary file. Note that since
array itself is an object we can write and read the whole array. We do not need to write a
loop to write/read each element of the array for a binary file. However for text files we
have to use loops.
Example 11: The following program write an array of objects, each of type class: Person
into a binary file and then reads the array from the binary file and displays the elements
of the array on the screen.
import java.io.*;
public class Main{
public static void main(String[] args) {
output();
input();
}
public static void output(){
Person[] p = new Person[3];
p[0] = new Person("John Doe", 45, "123456789");
p[1] = new Person("Jane Doe", 39, "456789999");
p[2] = new Person("James Bond", 75, "993456789");
try{
ObjectOutputStream st = new ObjectOutputStream(
new FileOutputStream("out.dat"));
st.writeObject(p);
st.close();
}catch(Exception e){
System.out.println("Error 1: " + e.getMessage());
System.exit(0);
}
}
public static void input(){
18
try{
ObjectInputStream st = new ObjectInputStream(
new FileInputStream("out.dat"));
Person[] p = new Person[3];
p = (Person[]) st.readObject();
for(int i = 0; i < p.length; i++)
System.out.println(p[i].getName() + ", " +
p[i].getAge() + ", " + p[i].getSS());
}catch(Exception e){
System.out.println("Error 2: " + e.getMessage());
System.exit(0);
}
}
}
Sample Output:
John Doe, 45, 123456789
Jane Doe, 39, 456789999
James Bond, 75, 993456789
Description:
There are two important lines in this program:
a) We write: st.writeObject(p).to write the whole array in to the binary file (We
cannot do this with a text file). We do not write:
for(int i = 0; i < p.length; i++)
st.writeObject(p[i]);
b) We write: p = (Person[]) st.readObject() to read from the file to all the
elements of the array. Note the casting is not: (Person). It is (Person[]). We do not write:
for(int i = 0; i < p.length; i++)
st.readObject(p[i]);
String Tokenizer
I just included this section to learn the string tokenizes. There are programs that we need
to read strings and extract the words of each string (The exercise at the end of this lecture
is of this nature). The Java class StringTokenizer can be used to deal with this problem.
Example 12. A program to read a sentence and prints every word.
import java.util.*;
import java.io.*;
public class Main{
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
System.out.println("Enter a line");
19
String s = key.nextLine();
StringTokenizer tok = new StringTokenizer(s);
while(tok.hasMoreTokens()){
String word = tok.nextToken();
System.out.println(word);
}
}
}
Sample Output:
Enter a line
This part is not in this section in your book.
This
part
is
not
in
this
section
in
your
book.
Description:
The instruction: StringTokenizer tok = new StringTokenizer(s) splits the string into
words. Now in the variable: tok we have these words. The points of segmentation of the
words is character space. For example the space between the words: This and part, or
the space between the words: part and is. In the while-loop:
while(tok.hasMoreTokens()){
String word = tok.nextToken();
System.out.println(word);
}
The method: tok.hasMoreTokens() returns true as long as there is a next token (a word).
The method: tok.nextToken() gets the next token (word).