You are on page 1of 28

Java Supplementary Material 5: More on file input and output

Java Supplementary Material 5

More on File Input and Output

Programming 2 © 2022-23 Slide SM5.1


D E Newton
Java Supplementary Material 5: More on file input and output
Objectives

• After you have read and studied this supplement, you should be
able to
 use File objects in your program to access the files on your
computer system;
 use a FileDialog object to easily select a particular file;
 write exception-handling code using try-catch blocks.

Programming 2 © 2022-23 Slide SM5.2


D E Newton
Java Supplementary Material 5: More on file input and output
The class File

• In this supplement you will learn more about file input and file
output i.e. about how to read data from a file and how to save
data to a file.
• We use the term “file access” to refer to both read and write
operations. If we need to be precise, we will write “read access”
or “write access”.
• Operating systems such as Windows, Linux and MacOS have
different methods of describing file systems and this presents a
problem for Java which is intended to be platform independent.
• Java overcomes this problem by providing a class File (in
java.io) that gives an abstract, system-independent view.

Programming 2 © 2022-23 Slide SM5.3


D E Newton
Java Supplementary Material 5: More on file input and output
Associating a Java File object with an actual file

• Suppose we want to read the contents of a file sample.data. In


order to access such a file, we often create a File object and
link, or associate, it with the file by calling the File constructor:
File inFile = new File("sample.data");
• In this example, the argument to the constructor is the name of
the file which is assumed to be located in the current directory.
• When the link is established by a successful call to the
constructor, we say the file is opened. A file must be opened
before it is possible to perform any file access operation.
• Associating a File object with a non-existent file does not
necessarily lead to an error. E.g. if we wish to write data to a
new file then initially the file does not exist. Only when we
actually start writing data will the file actually be created.
Programming 2 © 2022-23 Slide SM5.4
D E Newton
Java Supplementary Material 5: More on file input and output
Assumed directory structure

• It is also possible to access a file that is stored in a directory other


than the current directory. For the following examples, we
assume the directory structure shown below with chapter02 as
the current directory.
F:

java dbases

exercises examples

chapter01 chapter02 chapter03 chapter04

book-exercise
Programming 2 © 2022-23 Slide SM5.5
D E Newton
Java Supplementary Material 5: More on file input and output
Two forms of the constructor

• To access the file test.data in the directory exercises, we


can use either
inFile =
new File("F:/java/exercises/test.data");
or
inFile = new File("F:/java/exercises",
"test.data");
where, in the second version, the first argument passed to the
constructor is the directory pathname.
• These examples assume that we are using a Windows platform
where a pathname is normally specified using the backslash
character \ as the delimiter, like this:
F:\java\exercises\test.data

Programming 2 © 2022-23 Slide SM5.6


D E Newton
Java Supplementary Material 5: More on file input and output
Escape sequences in a Java String

• Unfortunately, however, the backslash symbol has special


significance when used inside a Java string: it is called an escape
character and is used to help specify a non-printable, control
character such as \n for a newline character.
• Other examples of escape sequences are
 \t for a tab character;
 \" to give a double quote " within a string;
 \\ to give a \ within a string.
and the string "\nHello" is six characters long, not seven !
• If using Windows, Java will automatically convert
"F:/java/exercises/test.data"
because this is a file-related string, to
"F:\\java\\exercises\\test.data" 
Programming 2 © 2022-23 Slide SM5.7
D E Newton
Java Supplementary Material 5: More on file input and output
Absolute & relative pathnames

• A pathname can either be absolute or relative to the current


directory.
• An absolute pathname is the full pathname beginning, in
Windows, with the disk drive name. For example,
"F:/java/exercises/test.data"
• A relative pathname is written relative to the current directory.
For example, if the current directory is chapter02 (as on Slide
5), then the relative pathname
"book-exercise/Book.java"
is equivalent to the absolute pathname
"F:/java/examples/chapter02/book-exercise/
Book.java"

Programming 2 © 2022-23 Slide SM5.8


D E Newton
Java Supplementary Material 5: More on file input and output
Relative pathname cont./

• And
"../chapter04"
is equivalent to the absolute pathname
"F:/java/examples/chapter04"
where the two dots (..) in the first string mean "the directory
above" i.e. the parent directory.

Programming 2 © 2022-23 Slide SM5.9


D E Newton
Java Supplementary Material 5: More on file input and output
File objects can be directories

• Peculiarly, a File object can also be associated with a directory.


After the association is made, we can list the contents of the
directory by calling the list() method of a File object. This
latter method will return a String array containing the required
information:
File directory =
new File("F:/java/examples/chapter02");
String[] filenames = directory.list();
for( String fname : filenames )
System.out.println(fname);

Programming 2 © 2022-23 Slide SM5.10


D E Newton
Java Supplementary Material 5: More on file input and output
isFile() method

• We can check whether a File object is associated with a file or


a directory by calling its boolean method isFile():
File file =
new File("F:/java/examples/chapter02");
if( file.isFile() )
System.out.println("This is a file");
else
System.out.println("This is a directory");

Programming 2 © 2022-23 Slide SM5.11


D E Newton
Java Supplementary Material 5: More on file input and output
Selecting a file using a FileDialog, LOAD or SAVE modes

• We can use a FileDialog object from the java.awt package to


let the user select a file or a directory. A FileDialog box has two
modes: LOAD and SAVE.
• You open the dialog in the LOAD mode if you want to read data
from the file that will be selected and in the SAVE mode if you want
to write data to the selected file.
• When the statements
FileDialog fileBox = new FileDialog(myFrame,
"Open", FileDialog.LOAD);
fileBox.setVisible(true);
are executed, the FileDialog box shown on the next slide
appears.
• The first argument myFrame, passed to the FileDialog
constructor, is a Frame object that is the owner or parent of the
dialogue box.
Programming 2 © 2022-23 Slide SM5.12
D E Newton
Java Supplementary Material 5: More on file input and output
FileDialog box
• The dialogue box
title is determined
by the second
argument "Open".
• This view assumes
we have navigated
to the folder
chapter02.
• If we select the file
readme.txt and
click on Open, the
dialog box will
close.

Programming 2 © 2022-23 Slide SM5.13


D E Newton
Java Supplementary Material 5: More on file input and output
The getFile() and getDirectory() methods of FileDialog

• After the dialog box closes, the name of the file selected,
readme.txt, is retrieved using the getFile() method. The
statement
String filename = fileBox.getFile();
assigns the name of the file selected to filename.
• Alternatively, if the Cancel button of the FileDialog is
clicked, then the getFile() method returns null.
• We can also get the pathname to the directory from which the
user selected the file. Continuing with the same example,
executing
String directoryPath = fileBox.getDirectory();
will assign the pathname
F:\java\examples\chapter02
to directoryPath.
Programming 2 © 2022-23 Slide SM5.14
D E Newton
Java Supplementary Material 5: More on file input and output
FileDialog in SAVE mode

• To select a file for saving data, we open the FileDialog in the


SAVE mode:
FileDialog fileBox = new FileDialog(owner,
"Save As", FileDialog.SAVE);
fileBox.setVisible(true);
• Apart from minor cosmetic differences (e.g. the dialog box title),
the only difference in SAVE mode concerns what happens when the
user selects an existing file. A warning dialogue box is displayed
which allows the user to modify their choice if they do not wish to
overwrite the file.
• Once a file is opened by properly associating a File object to it,
the actual file access can commence.

Programming 2 © 2022-23 Slide SM5.15


D E Newton
Java Supplementary Material 5: More on file input and output
Exceptions revisited

• Many file-related methods and constructors throw Exceptions. As


was mentioned in Java Supplementary Material 4, these are the way in
which Java indicates that an abnormal condition has occurred.
• If an exception occurs whilst executing a constructor (or method),
we deal with these in one of two ways: either we propagate it or we
catch it.
 We propagate (i.e. re-throw) the exception to whichever method
called this method (by adding a throws clause to this method's
header).
 An example of this, from SM4 is
public void readAnimalData(String fileName)
throws FileNotFoundException

Programming 2 © 2022-23 Slide SM5.16


D E Newton
Java Supplementary Material 5: More on file input and output
Exceptions must be caught or propagated

 We catch the exception by providing code within this method


which will "process" the exception if it should occur at
runtime.
 To do this, any code that may possibly generate a thrown
exception must be placed into a try block.
 The code in a try block may contain code that cannot
throw an exception but this does not mean that you
should put all of that method’s code into the try block.
 The try block is followed by a catch block which will
contain exception-handling code to process that exception.

Programming 2 © 2022-23 Slide SM5.17


D E Newton
Java Supplementary Material 5: More on file input and output
Propagating an IOException

• In the example below, the method throws any IOException that


might occur:
public void readFile (String[] args)
throws IOException
{
.... = new FileOutputStream(outFile);
...
outStream.write(byteArray);
...
outStream.close();
}
Therefore we add
These method/constructor calls throws IOException
may throw an IOException. to the method header.
• If an IOException is thrown by the method close(), for
example, then the method readFile() propagates this thrown
exception to the code which called
© 2022-23
this method.
Programming 2 Slide SM5.18
D E Newton
Java Supplementary Material 5: More on file input and output
Exception handling cont./

• Now consider this scenario:


 the monthly rainfall figures (in mm) for January through to
December have been written as ints to a file;
 we are asked to write a class with methods for:
 reading in rainfall data from such a file;
 displaying the rainfall data;
 computing the average monthly rainfall figure.

Programming 2 © 2022-23 Slide SM5.19


D E Newton
Java Supplementary Material 5: More on file input and output
Exception handling code example

Code example SM5


Rainfall project
•Examine the source code on Handout SM5:

 see lines 39-52 for the first try block followed by lines
55-59 which will be executed if a EOFException occurs;
 lines 63-66 which will be executed if a FNFException
occurs;
 lines 70-73 which will be executed if an IOException
occurs.
 Note an alternative, older way of linking the data files
with the File object on lines 43-44. Do NOT use this
way.
Programming 2 © 2022-23 Slide SM5.20
D E Newton
Java Supplementary Material 5: More on file input and output
Exception handling code example cont./

• If we now generate an exception by executing the


readRainfallData() method but then deliberately misspell
the filename e.g. ranfall.data:
 because the file does not exist, an exception will be thrown;
 the exception, declared as ex on line 61 in this example, is
"caught" with control passing to the catch block on lines
63-66.

Programming 2 © 2022-23 Slide SM5.21


D E Newton
Java Supplementary Material 5: More on file input and output
Exception handling code example cont./
• A different exception will be thrown if there is not enough data
in the file. If we edit our data file so that it has e.g. only eleven
numbers …
 then this time an EOFException is thrown at line 53 as the
end of the file is reached before the twelfth rainfall figure is
read.
• Note that after executing a catch block, control passes to the
next statement after the try-catch block structure.
 In this example, control passes to line 75 and the method
completes execution.

Programming 2 © 2022-23 Slide SM5.22


D E Newton
Java Supplementary Material 5: More on file input and output
Exception handling code example cont./
• A third catch block relates to an IOException:
 as can be seen on line 71, a call to printStackTrace()
is made. This method is an instance method of the
Exception class, the superclass for an IOException;
 in BlueJ, the output from this error is displayed, in red,
in the lower half of the terminal window;
 the stack trace tells us what type of error has been
"caught" and where that error occurred (or, strictly
speaking, where the exception was thrown).

Programming 2 © 2022-23 Slide SM5.23


D E Newton
Java Supplementary Material 5: More on file input and output
Exception handling code example cont./
• Note that although the code was set up to "catch" IOExceptions,
the exceptions that were actually caught in the explanation were a
FileNotFoundException and an EOFException.
• This is because FileNotFoundException and EOFException are
both particular types of IOExceptions (in the same way that both
Car and Bicycle are particular types of Vehicles).
• If a method may throw a range of exceptions then the throws
clause is written to include only the superclass exception e.g. in this
case throws IOException
• It is not necessary to include any mention of EOFException as
EOFException is a subclass of the IOException class, and
including the clause throws IOException in the header will
"throw" both an IOException and any EOFException since
EOFException "is" an IOException.

Programming 2 © 2022-23 Slide SM5.24


D E Newton
Java Supplementary Material 5: More on file input and output
Ordering of catch blocks

• In any sequence of catch blocks:


 it is essential that subclasses of the more specific exception
superclass are tested for first;
 the catch blocks corresponding to the
FileNotFoundException and EOFException
exceptions must come before the catch block for their
superclass IOException.
 If, for example, the EOFException and the IOException
catch blocks are interchanged, the compilation will fail with
an error message indicating that the EOFException is
unreachable (as it is a subclass of the IOException class).

Programming 2 © 2022-23 Slide SM5.25


D E Newton
Java Supplementary Material 5: More on file input and output
A simple approach to exception handling
• A very simple approach to exception handling could be: if an
IOException occurs then
 a warning message is displayed;
 details are given, using printStackTrace(), of the chain
of method calls prior to the exception being raised;
 some code is executed to "deal with" the exception.
• In our example, "dealing with" the exception meant making sure
that the data filename was set to null so that the other methods
would be aware that no data was available.
• This type of approach is widely adopted when we only require
the method to provide minimal handling of the exception and to
prevent the program from "crashing" in an uncontrolled fashion.

Programming 2 © 2022-23 Slide SM5.26


D E Newton
Java Supplementary Material 5: More on file input and output
Exceptions handled by the Java interpreter
• When an exception occurs at execution time, a method that throws
an exception relies on its caller to either handle the exception or to
propagate it further.
• If a thrown exception is not handled by any method in the
propagation chain, the Java interpreter will eventually handle it.
• For example, if we attempt to write to the file "tmp" which is
actually a folder, not a file, then we get output like this:
Exception in thread "main" java.io.FileNotFoundException:
tmp (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
at FileOutputStreamApp.main(FileOutputStreamApp.java:14)
• This is a stack trace showing that the exception was originally
thrown in the private method open() of the FileOutputStream
class and has propagated until it is eventually caught by the Java
interpreter.
Programming 2 © 2022-23 Slide SM5.27
D E Newton
Java Supplementary Material 5: More on file input and output
Handling other exceptions
• In the event that some other type of unexpected exception occurs
e.g. IndexOutOfBoundsException which will not be caught
by the catch blocks, the Java Interpreter will handle it in the usual
way. But we could add a final catch block to catch any exception:
catch(Exception ex)
{
// warning message only here
}
• Alternatively, we could add a catch block specifically targeted at
catching an IndexOutOfBoundsException or, indeed, any
other particular type of exception e.g. NullPointerException.
• Also note that if there is code that should always be executed,
whether or not an exception occurs, then a finally block can be
added.

Programming 2 © 2022-23 Slide SM5.28


D E Newton

You might also like