Lecture 9 File Handling in Java

Download Report

Transcript Lecture 9 File Handling in Java

File handling in Java
File class
• The file class is used to store the path and
name of a directory or file.
• The file object can be used to create,
rename, or delete the file or directory it
represents.
File Class Constructors
• The File class has the following constructors • File(String pathname); // pathname could be file
or a directory name
•
File(String dirPathname, String filename);
•
File(File directory, String filename);
• The File class provides the getName() method
which returns the name of the file excluding the
directory name.
• String getName();
Introduction
• Within computing it should be simple to do
simple things.
• Reading data from a file should be a
simple operation; however, within Java this
is not reflected in terms of simple,
straightforward file I/O classes.
Using the Scanner Class
First Consider our leap year
Program
• // Second Program HelloWorld
• import java.util.Scanner;
• public class Leapyear {
•
public static void main(String args []){
•
Scanner input = new Scanner( System.in );
•
String theName = input.nextLine();
•
int num1 = Integer.parseInt(theName);
•
if(num1 % 4 ==0 && (num1 % 100 != 0 ||num1 % 400 == 0))
•
System.out.println("leap");
•
else
•
System.out.println("not leap");
•
}}
Note
• Input is gained from system.in that is the
screen
Example our leap year program
import java.lang.*;
import java.io.*;
// Second Program HelloWorld
import java.util.*;
public class Leapyear2 {
public static void main(String args []){
try
{
Scanner input = new Scanner( new File("fred2.txt") );
String theName = input.nextLine();
int num1 = Integer.parseInt(theName);
if(num1 % 4 ==0 && (num1 % 100 != 0 ||num1 % 400 == 0))
System.out.println("leap");
else
System.out.println("not leap");
}
• catch (Exception e)
•
{
•
System.err.println("File
input error");
•
}
• }
• }
Handling Exceptions
• You may be wondering what the purpose of the try { .. }
catch block is. Rather than checking for erroneous return
values (such as a null pointer when obtaining an output
stream as is the case with C's fopen), we catch
exceptions.
• Exceptions are events that occur in exceptional or
unusual circumstances, such as error conditions. A
method can throw an exception, to indicate to the calling
object that a non-standard circumstance has occurred.
Thus, instead of checking each and every file method
call, we have one piece of code handling all possible
errors!
Errors
• When an error occurs within a method, the
method creates an object and hands it off to the
runtime system.
• The object, called an exception object, contains
information about the error, including its type
and the state of the program when the error
occurred.
• Creating an exception object and handing it to
the runtime system is called throwing an
exception.
The Call stack
• After a method throws an exception, the
runtime system attempts to find something
to handle it.
• The set of possible "somethings" to handle
the exception is the ordered list of
methods that had been called to get to the
method where the error occurred.
• The list of methods is known as the call
stack
Exception Handlers
• The runtime system searches the call
stack for a method that contains a block of
code that can handle the exception.
• This block of code is called an exception
handler.
• The exception handler chosen is said to
catch the exception.
• If the runtime system exhaustively
searches all the methods on the call stack
without finding an appropriate exception
handler, the runtime system (and,
consequently, the program) terminates.
Three Kinds of exception
• Checked exceptions - Exceptional
Conditions that an application should
anticipate and recover from. For example
a FileNotFoundException.
• Errors – Exceptional Conditions external to
the application for example a system
malfunction. Usually cannot be anticipated
• Runtime exception- Exceptions internal to
the application e.g. divide by 0.
Try block
try {
code
}
catch block
Code is the method body that performs the
functionality of your method
Enclosing it in a try block throws the exception to
the runtime system for catching i.e. exception
handling by the catch block.
Catch blocks
try {
}
catch (ExceptionType name) {
}
catch (ExceptionType name) {
}
Catch Block
• Each catch block is an exception handler and
handles the type of exception indicated by its
argument.
• The argument type, ExceptionType, declares the
type of exception that the handler can handle
and must be the name of a class that inherits
from the Throwable class.
• The handler can refer to the exception with
name.
Catch Block code
• The catch block contains code that is executed if
and when the exception handler is invoked.
• The runtime system invokes the exception
handler when the handler is the first one in the
call stack whose ExceptionType matches the
type of the exception thrown.
• The system considers it a match if the thrown
object can legally be assigned to the exception
handler's argument.
Example
try { “file handling code”
}
catch (FileNotFoundException e) {
System.err.println("FileNotFoundException: “ +
e.getMessage());
}
catch (IOException e) {
System.err.println("Caught IOException: "
+ e.getMessage());}
Streams
• Java 1.0 used 8-bit input and output streams,
however, this did not support internationalised
character sets (e.g. Chinese, etc.).
• Java 1.1 tried to correct this problem by
introducing corresponding 16-bit I/O streams.
• However, the correction was not complete, and
8-bit streams are still used for binary I/O,
keyboard I/O, etc.
• A large number of I/O classes are provided, to
the extent where it can be confusing to know
what particular type of I/O class should be used.
Data Streams
• A disk based file is one possible source, or sink, for data.
• However, data may also be gathered from other sources,
e.g. a keyboard, network connection, etc.
• Java employs the notion of a stream as an higher level
abstraction for all possible data sources.
• Hence, in Java, a stream might be receiving bytes from
(or sending them to) a file, a String object, a network
socket, the keyboard, etc.
• Fundamentally, a stream is a flow of data, never mind
where it comes from or goes to.
Manipulating Streams
• Functionally, data can be added to, or
plucked from a stream.
• Java 1.0 made use of 8-bit streams;
however, this was not adequate when
dealing with external character sets, e.g.
Unicode.
• To overcome this, Java1.1 introduced 16bit Reader and Writer classes intended for
all character I/O.
• Each streams offers one type of I/O service (e.g.
character I/O, binary I/O,byte array I/O, file I/O,
etc.).
• It is intended that the programmer connect
several streams to get the exact type of
processing required.
• I/O streams can be easily connected to one
another by passing one stream as an argument
to the other streams constructor, e.g.:
BufferedReader file = new BufferedReader( new FileReader( selectedFile ) );
• Java provides a useful input stream known as
DataInputStream, which offers methods for reading
characters, integers, floats, etc.
• However, only one constructor is defined for the class:
java.io.DataInputStream( java.io.InputStream ).
• Given this, how can a DataInputStream be used to read
information from a disk file?
• Within Java, streams are designed to be layered on top
of each other, entailing that the programmer must
connect together several (usually two) streams to get the
exact type of required functionality.
• Hence, in order to read data from a diskfile
we firstly need to use the FileInputStream,
which possesses the following constructor
• FileInputStream( String filename ), i.e.
permitting a stream to be opened to a
specified disk file.
Making a stream connection
• Using a FileInputStream a stream connection can be made to a disk
file.
• However, the FileInputStream only provides methods for reading
byte arrays from the disk file. In order to read integers, floats, etc. it
is necessary to append a DataInputStream onto the
FileInputStream, e.g.
• FileInputStream fileStream = new FileInputStream( “file.dat” );
• DataInputStream dataStream = new DataInputStream( fileStream );
• or simply just:
• DataInputStream dataStream = new DataInputStream( new
FileInputStream( “file.dat” ) );
java.io package
• Classes related to input and output are
present in the JavaTM language package
java.io .
• Java technology uses "streams" as a
general mechanism of handling data.
• Input streams act as a source of data.
• Output streams act as a destination of
data.
Byte Streams
• The package java.io provides two set of
class hierarchies - one for handling
reading and writing of bytes, and another
for handling reading and writing of
characters.
• The abstract classes InputStream and
OutputStream are the root of inheritance
hierarchies handling reading and writing of
bytes respectively.
public abstract class InputStream
• This abstract class is the superclass of all
classes representing an input stream of
bytes.
• Applications that need to define a direct
subclass of InputStream must always
provide a method
• that returns the next byte of input.
Figure : InputStream class
hierarchy (partial)
Methods on Input Stream
JDK classes
• JDK classes that extend the InputStream
class include:
• • BufferedInputStream
• • ByteArrayInputStream
• • DataInputStream
• • FilterInputStream
• • PushbackInputStream
public abstract class OutputStream
• This abstract class is the superclass of all
classes representing an output stream of
bytes. An output stream accepts output
bytes and sends them to some sink.
• Applications that need to define a subclass
of OutputStream must always provide at
least a method that writes one byte of
output.
Figure : OutputStream class
hierarchy (partial)
OutputStream methods
Subclasses of OutputStream
• Classes that extend OutputStream
include:
• • BufferedOutputStream
• • ByteArrayOutputStream
• • DataOutputStream
• • FilterOutputStream
FileOutputStream
•
•
•
•
The FileOutputStream is an output stream for
writing data to a File object or to a suitable file
descriptor.
The FileOutputStream class provides constructors that
accept either a reference to a File object (explored later)
or alternatively a String object referring to the name of
the file that should be opened.
• Methods are provided for writing out various byte
structures to the disk file (either the entire array can be
written, or a specific subsection).
• The close method is used to close the file once no more
output is needed.
• The FileInputStream interface is similar to
that of the FileOutputStream:
• The constructors and read methods are
simply counterparts to those found in
FileOutputStream
• However, the FileInputStream defines the
skip(long n) method which permits a
certain number of bytes in the file to be
‘jumped’ over.
Data Streams
• Normally the DataOutputStream and
DataInputStream classes are used to
further extend the capabilities of the file
classes, and are explored next.
Data Output Stream
• DataOutputStream extends the basic functionality of the
OutputStream class, as follows:
• As before functions are included for writing out arrays of
bytes, but now, methods are provided for writing out
characters (individually or as an array), numbers
(integers, floating point, short ints), etc.
• The writeUTF( String str ) method is deserved of special
mention. The method is intended to write out an
unformatted text field. This method is often employed
when writing character data to a file.
• The flush() method is used to write any buffered output
to the file, useful to guarantee that all information is
correctly saved.
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
public class java.io.DataOutputStream
{
public DataOutputStream( OutputStream out );
public void flush();
public void write( byte b[], int off, int len);
public final void writeBoolean( bollean v );
public final void writeByte( int v );
public final void writeBytes( String s );
public final void writeChar( int v );
public final void writeChars( String s );
public final void writeDouble( double v );
public final void writeFloat( float v );
public final void writeInt( int v );
public final void writeLong( long v );
public final void writeShort( int v );
public final void writeUTF( String str );
}
DataInputStream
• This class is a counterpart to
DataOutputStream, offering corresponding
functionality except dealing with input from
a file. Methods follow:
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
public class java.io.DataInputStream
{
public DataInputStream( InputStream out );
public final int read( byte b[] );
public final boolean readBoolean();
public final byte readByte();
public final char readChar();
public final double readDouble();
public final float readFloat();
public final int readInt();
public final String readLine();
public final long readLong();
public final short readShort();
public final String readUTF();
public final int skipBytes( int n );
}
read and write methods
• InputStream class defines the following
methods for reading bytes •
int read() throws IOException
•
int read(byte b[]) throws IOException
•
int read(byte b[], int offset, int length)
throws IOException
• Subclasses of InputStream implement the
above mentioned method
Write methods
• OutputStream class defines the following
methods for writing bytes •
void write(int b) throws IOException
•
void write(byte b[]) throws IOException
•
void write(byte b[], int offset, int length)
throws IOException
• Subclasses of OutputStream implement
the above mentioned methods.
The example below illustrates
code to read a character.
• First create an object of type
FileInputStream type using the name of
the file.
FileInputStream inp = new FileInputStream("filename.ext");
• //Create an object of type
DataInputStream using inp.
• DataInputStream dataInp = new DataInputStream(inp);
•
int i = dataInp.readInt();
Adapting our leap year example
•
•
•
•
•
•
import java.lang.*;
import java.io.*;
// Second Program HelloWorld
import java.util.*;
public class Leapyear3 {
public static void main(String args []){
•
•
•
try
{
FileInputStream inp = new
FileInputStream("fred2.txt");
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
//Create an object of type DataInputStream using inp.
DataInputStream dataInp = new DataInputStream(inp);
int num1 = dataInp.readInt();
//Scanner input = new Scanner( new File("fred2.txt") );
//String theName = input.nextLine();
//int num1 = Integer.parseInt(theName);
if(num1 % 4 ==0 && (num1 % 100 != 0 ||num1 % 400 == 0))
System.out.println("leap");
else
System.out.println("not leap");
}
catch (Exception e)
{
System.err.println("File input error");
}
}
}
Reader and Writer classes
Similar to the InputStream and OutputStream class hierarchies for
reading and writing bytes, Java technology provides class
hierarchies rooted at Reader and Writer classes for reading and
writing characters.
• Java programs use 16 bit Unicode character encoding to represent
characters internally.
• Other platforms may use a different character set (for example
ASCII) to represent characters.
• The reader classes support conversions of Unicode characters to
internal character shortage.
• Every platform has a default character encoding.
• Besides using default encoding, Reader and Writer classes can also
specify which encoding scheme to use.
The Reader class hierarchy is
illustrated below.
The Writer class hierarchy is
illustrated below.
A brief overview of key Reader
classes.
• CharArrayReader The class supports reading
of characters from a character array.
• InputStreamReader The class supports reading
of characters from a byte input stream. A
character encoding may also be specified.
• FileReader
The class supports reading of
characters from a file using default character
encoding.
•
A brief overview of key Writer
classes.
• CharArrayWriter The class supports writing of
characters from a character array.
• OutputStreamReader The class supports writing
of characters from a byte output stream. A
character encoding may also be specified.
• FileWriter The class supports writing of
characters from a file using default character
encoding.
Example
• The example below illustrates reading of
characters using the FileReader class.
//Create a FileReader class from the file
name.
FileReader fr = new
FileReader("filename.txt");
int i = fr.read(); //Read a character
Output Example
import java.io.*;
class FileOutputDemo
{
public static void main(String args[])
{
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object
try
{
// Create a new file output stream
// connected to "myfile.txt"
out = new FileOutputStream("myfile.txt");
// Connect print stream to the output stream
p = new PrintStream( out );
p.println ("This is written to a file");
p.close();
}
catch (Exception e)
{
System.err.println ("Error writing to file");
}
}
}
File Input demo
import java.io.*;
class FileInputDemo
{
public static void main(String args[])
{
// args.length is equivalent to argc in C
if (args.length == 1)
{
try
{
// Open the file that is the first command line parameter
FileInputStream fstream = new FileInputStream(args[0]);
// Convert our input stream to a DataInputStream
DataInputStream in = new DataInputStream(fstream);
// Continue to read lines while there are still some left to read
while (in.available() !=0)
{
// Print file line to screen
System.out.println (in.readLine());
}
in.close();
}
catch (Exception e)
{
System.err.println("File input error");
}
}
else
System.out.println("Invalid
parameters");
}
}
Some swing and file handling
Top Level Containers: JFileChooser
63
JFileChooser
• javax.swing.JFileChooser:
– Allows the the user to choose a file
– Supports “open” and “save”:
showOpenDialog(),showSaveDialog()
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(null);
if(returnVal ==
JFileChooser.APPROVE_OPTION)
System.out.println("File: " +
fc.getSelectedFile());
Example Program
• Using JFileChooser
import javax.swing.*;
import java.awt.BorderLayout;
public class Second {
public static void main(String[] args) {
JFrame frame = new JFrame("My First Frame");
// operation to do when the window is closed.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(new JLabel("I Love Swing"),
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(null);
if(returnVal ==
JFileChooser.APPROVE_OPTION)
System.out.println("File: " +
fc.getSelectedFile());
}
}
Amending this to choose a file for
input
import javax.swing.*;
import java.awt.BorderLayout;
import java.io.*;
public class Third {
public static void main(String[] args) {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION)
System.out.println("File: " + fc.getSelectedFile());
Next
try
{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new
FileInputStream(fc.getSelectedFile());
// Convert our input stream to a
// DataInputStream
DataInputStream in =
new DataInputStream(fstream);
finally
// Continue to read lines while
// there are still some left to read
while (in.available() !=0)
{
// Print file line to screen
System.out.println (in.readLine());
}
in.close();
}
catch (Exception e)
{
System.err.println("File input error");
}
}
}
And Using this to save a file for
Output
import javax.swing.*;
import java.awt.BorderLayout;
import java.io.*;
public class Fourth {
public static void main(String[] args) {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showSaveDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION)
System.out.println("File: " + fc.getSelectedFile());
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object
try
{
// Create a new file output stream
// connected to "myfile.txt"
out = new FileOutputStream(fc.getSelectedFile());
// Connect print stream to the output stream
p = new PrintStream( out );
p.println ("This is written to a file");
p.close();
}
catch (Exception e)
{
System.err.println ("Error
writing to file");
}
}
}