Title: Intro to Computer Science II
1Intro to Computer Science II
- Chapter 11
- Files and Streams
- Data processing with sequential files
2Files (1)
- A file is an organized collection of data stored
on an external storage device such as a disk or
CD-ROM. - At the lowest level a file is a sequence of bytes
stored on an external storage device. - At a higher level a file may be organized into a
sequence of data items (lines, records or
objects, for example). - Files can be sequential or direct access.
3Files (2)
- Physically, files are organized in tracks and
sectors on a disk that are linked together - A File Allocation Table (FAT) keeps track of each
file (name, access rights) on the disk - It is inefficient to read a file one byte at a
time since disk access is a thousand times slower
than access in RAM or ROM memory. - Therefore files are "buffered" read and written
one data buffer (e.g. 4096 bytes) at a time.
4Files (3)
- Data buffers reside in main memory as part of a
File Control Block (FCB) that describes the file - To access a file it is first necessary to open it
- This associates an FCB in memory with the file
- When access to a file is no longer required it is
necessary to close the file - This disassociates the FCB and the file.
5Reading a sequential file
- Open file for reading (error if file does not
exist) - Read a data item (byte, line, record) from file
- WHILE not at end of file DO
- Process the data item
- Read the next data item
- END WHILE
- Close the file
if there isn't one end of file will be signalled
6Writing a sequential file
default is often to overwrite an existing file
-
- Open the file for writing
- WHILE there are data items to write DO
- write the next data item
- END WHILE
- Close the file
7Two kinds of sequential files
- Text files
- A text file is a file of lines that is "human
readable". The bytes in these files are
interpreted as ASCII codes. End of lines are
indicated by one or more special characters
(cr-lf in Windows, lf in Unix) - Binary files
- These are files of bytes whose values are not
interpreted as ASCII codes. Machine language
files and Java bytecode files are examples of
binary files. - ASCII codes are 7-bit codes forming a subset of
Unicode
8Binary text representation
- The integer 123526 is represented internally as
the 32-bit binary number - 00000000 00000001 11100010 10000110
- (0256256256 1256256 226256
134) - The corresponding text string "123526" is
represented as the 6 bytes of ASCII codes - 00110001 00110010 00110011 00110101
- 00110010 00110110
9Streams and files (1)
- More general concept than a file
- A stream is a sequence of data items
- A stream need not be connected to a file
- Streams can also be connected together (output of
one stream is input to another stream) - To read a file connect an input stream to it
- To write a file connect an output stream to it
10Streams and files (2)
- In Java there are two basic kinds of streams
- Byte stream
- a stream of byte values
- a byte is 8-bits
- Character stream
- a stream of bytes to be interpreted as unicode
characters each character is two bytes - Encoding and decoding methods are specified to
convert between bytes and characters
11Byte Streams and files
Diskcontainingfiles
Program
input stream
output stream
Your program can connect streams to files
12Unicode decoding/encoding
Diskcontainingfiles
Program
input stream
decoder
Diskcontainingfiles
Program
output stream
encoder
13Some Java byte streams
InputStream
OutputStream
(Abstract)
(Abstract)
ByteArrayInputStream
ByteArrayOutputStream
FileInputStream
FileOutputStream
FilterInputStream
FilterOutputStream
BufferedInputStream
BufferedOutputStream
DataInputStream
DataOutputStream
ObjectInputStream
ObjectOutputStream
Not all classes are shown
14Some character streams
Reader
Writer
(Abstract)
(Abstract)
BufferedReader
BufferedWriter
InputStreamReader
OutputStreamWriter
FileReader
FileWriter
PrintWriter
Not all classes are shown
15Buffering a stream
- It can be inefficient to read from a stream or
write to a stream one byte at a time - It is more efficient to use an array of bytes as
a "buffer", 4096 bytes for example. - Now the program can read from the buffer and
whenever the buffer becomes empty it can be
filled again by the stream
16Two kinds of buffering
Diskcontainingfiles
Program
OperatingSystem
buffer
buffer
Program controls this buffering
Operating System controls this buffering
17Input stream prototypes
Construct an input byte stream connected to a file
public FileInputStream(String fileName) throws
FileNotFoundException
Disk
Program
FIS
this is new
Construct a buffered input byte stream
public BufferedInputStream(InputStream in)
BIS
18Input stream example (1)
Open a byte stream for input from a file
FileInputStream fin new FileInputStream("in.dat"
)
Open a buffered input byte stream (connecting
streams)
FileInputStream fin new FileInputStream("in.dat"
) BufferedInputStream in new
BufferedInputStream(fin)
Do it in one step (connecting streams)
BufferedInputStream in new
BufferedInputStream(new FileInputStream("in.dat"))
A FileInputStream "is a" InputStream
19Input stream example (2)
Disk
Program
FIS
BIS
Buffering a FileInputStream using a
BufferedInputStream
BufferedInputStream in new
BufferedInputStream(new FileInputStream("in.dat"))
20Output stream prototypes
Construct an output byte stream connected to a
file
public FileOutputStream(String fileName) throws
FileNotFoundException
Disk
Program
this is new
FOS
Construct a buffered output byte stream
public BufferedOutputStream(OutputStream out)
21Output stream example (1)
Open an output file as a byte stream
FileOutputStream fout new FileOutputStream("out.d
at")
Open a buffered output file as a byte stream
FileOutputStream fout new FileOutputStream("out.d
at") BufferedOutputStream out new
BufferedOutputStream(fout)
Do it in one step (connecting streams)
BufferedOutputStream out new
BufferedOutputStream( new
FileOutputStream("out.dat"))
A FileOutputStream "is a" OutputStream
22Output stream example (2)
Disk
Program
FOS
BOS
Buffering a FileOutputStream using a
BufferedOutputStream
BufferedOutputStream out new
BufferedOutputStream( new
FileOutputStream("out.dat"))
23Reader stream prototypes
Construct an input character stream that does the
decoding from bytes to characters
public InputStreamReader(InputStream in)
Construct a character stream from an input file
public FileReader(String fileName) throws
FileNotFoundException
Construct a buffered input character stream
public BufferedReader(Reader in)
24Reader example (1)
Opening input file for a character stream
InputStreamReader in new InputStreamReader(
new FileInputStream("in.dat"))
This can be simplified using FileReader
FileReader in new FileReader("in.dat")
Buffering an input character stream
BufferedReader in new BufferedReader(
new FileReader("in.dat")
25Reader example (2)
Disk
Program
FIS
BR
ISR
FR
Combine decoding andreading from a file
26Connecting Input Streams
Higher Level Reader
Disk
Program
FileReader
BufferedReader
BufferedReader in new BufferedReader(
new FileReader(fileName))
27Writer stream prototypes
Construct an output character stream that does
the encoding from characters to bytes
public OutputStreamWriter(OutputStream out)
Construct an output file as a character stream
public FileWriter(String fileName) throws
IOException
Construct a buffered output character stream
public BufferedWriter(Writer out)
28Writer example (1)
Opening output file for a character stream
OutputStreamWriter out new
OutputStreamWriter( new FileOutputStream("ou
t.dat"))
This can be simplified using FileWriter
FileWriter out new FileWriter("out.dat")
Buffering an output character stream
BufferedWriter out new BufferedWriter(
new FileWriter("out.dat")
29Writer example (2)
Disk
Program
FOS
BW
OSW
FW
Combine Encoding andwriting to a file
30The File class
A File object can be used to represent a file
File outFile new File("out.dat")
The constructors that have file name arguments
can also take a File object as an argument The
File object has some useful methods for
determining whether a file exists, for deleting a
file, or renaming a file and other useful
operations.
31Summary (1)
Opening a file for input as a buffered byte stream
BufferedInputStream in new
BufferedInputStream(new FileInputStream("in.dat"))
Opening a file for output as a buffered byte
stream
BufferedOutputStream out new BufferedOutputStrea
m(new FileOutputStream("out.dat"))
Opening a file for input as a buffered character
stream
BufferedReader in new BufferedReader(new
FileReader("in.dat"))
Opening a file for output as a buffered character
stream
BufferedWriter out new BufferedWriter(new
FileWriter("out.dat"))
32Summary (2)
Byte or Byte-block at a time file I/O
FIS, or BIS ? FIS FOS, or BOS ? FOS
Character or Character-block at a time file I/O
FR, or BR ? FR FW, or BW ? FW
Line at a time file I/O
BR ? FR PW ? FW, or PW ? BW ? FW
33Some unchecked exceptions
unchecked exceptions
java.lang.Throwable
java.lang.Exception
java.lang.RunTimeException
java.lang.IllegalArgumentException
java.lang.NumberFormatException
java.lang.IllegalStateException
java.lang.NoSuchElementException
34Some checked exceptions
java.lang.Throwable
java.lang.Exception
java.io.IOException
java.io.EOFException
java.io.FileNotFoundException
These exceptions must either be caught or
indicated in the throws clause the method.
Unchecked exceptions do not need to be indicated
in a throws clause
35Reading a byte stream (1)
Some methods from the Abstract InputStream class
public abstract int read() throws
IOException public int read(byte b) throws
IOException public int read(byte b, int
startPos, int numBytes) throws
IOException public void close() throws IOException
The single-byte read method reads a byte and
returns it as an integer. The return type cannot
be of type byte since we need a sentinal value of
-1 to indicate end of file. The int type is
32-bits so there is lots of room for the values 0
to 255 and the negative value -1.
36Reading a byte stream (2)
Byte at a time input model
FileInputStream in new FileInputStream("in.dat")
int n in.read() while (n ! -1) //
process the byte value in n here n
in.read() // and try to read another byte
More compact form
FileInputStream in new FileInputStream("in.dat")
int n while ( (n in.read()) ! -1) //
process the byte value in n here
37Reading a byte stream (3)
Buffered byte at a time input model
BufferedInputStream in new
BufferedInputStream( new FileInputStream("in
.dat")) int n while ( (n in.read()) ! -1)
// process the byte value in n here
There are actually two levels of buffering (1)
operating system buffers data from the disk (2)
buffered reader buffers the data from operating
system
38Reading a byte stream (4)
Byte array input model
BufferedInputStream in new
BufferedInputStream( new FileInputStream("in
.dat")) byte b new byte1024 int
numBytes while ( (numBytes in.read(b)) !
-1) // process b0 to bnumBytes - 1
here
Here the read method returns the number of bytes
actually read or -1 if there are no more bytes
(end of file)
39Writing a byte stream (1)
Some methods from the Abstract OutputStream class
public abstract void write(int b) throws
IOException public void write(byte b) throws
IOException public void write(byte b, int
startPos, int numBytes) throws
IOException public void flush() throws
IOException public void close() throws IOException
Any concrete classes that extend OutputStream
must implement the single byte write method.
40Writing a byte stream (2)
Reading, processing, and writing single bytes
BufferedInputStream in new
BufferedInputStream( new
FileInputStream("in.dat")) BufferedOutputStream
out new BufferedOutputStream( new
FileOutputStream("out.dat")) int n while ( (n
in.read()) ! -1 ) // process byte value in
n here out.write(n) // write it to the output
file in.close() // don't forget to close
files out.close()
41Writing a byte stream (3)
Reading, processing, and writing byte arrays
BufferedInputStream in new
BufferedInputStream( new
FileInputStream("in.dat")) BufferedOutputStream
out new BufferedOutputStream( new
FileOutputStream("out.dat")) byte b new
byte1024 int numBytes while ( (numBytes
in.read(b)) ! -1 ) // process b0 to
bnumBytes - 1 here out.write(b, 0,
numBytes) // write buffer to file in.close()
out.close()
42FileCopier (1)
import java.io.IOException import
java.io.FileInputStream import
java.io.File import java.io.FileNotFoundException
import java.io.BufferedInputStream import
java.io.FileOutputStream import
java.io.BufferedOutputStream public class
FileCopier private File inFile private
File outFile public FileCopier(File inFile,
File outFile) this.inFile inFile
this.outFile outFile
43FileCopier (2)
construct streams in a try block
public void copyFile() final int
END_OF_FILE -1 BufferedInputStream in
null BufferedOutputStream out null
try in new BufferedInputStream
( new FileInputStream(inFile))
out new BufferedOutputStream(
new FileOutputStream(outFile))
44FileCopier (3)
read input file and copy it to the output file
byte b new byte4096 int
numBytes while ( (numBytes
in.read(b)) ! END_OF_FILE )
// write bytes b0 to bnumBytes 1
out.write(b, 0, numBytes)
in.close() out.close()
catch (FileNotFoundEception e)
System.out.println("Input file .... ")
catch (IOException e)
System.out.println("Unknown IO error")
45FileCopier (4)
try to close the files
finally // always executed
try if (in
! null) in.close() if (out !
null) out.close()
catch (IOException e)
System.out.println("Error closing files")
// end of copyFile
method
46FileCopier (5)
Get file names as command line arguments
public static void main(String args)
if (args.length 2) File inFile new
File(args0) File outFile new
File(args1) FileCopier copier
new FileCopier(inFile, outFile)
copier.copyFile() else
System.out.println("args inFileName ...")
System.exit(0) // end class
book-projects/chapter11/files
47FileCopier with Eclipse
- Run it using command line arguments.
- From Run menu select Open Run Dialog...
- Select Arguments tab
- In Program arguments box enter following
arguments and click run - files/in.dat files/out.dat
- This assumes there is a subdirectory of the
project directory called files - Refresh the project to see file out.dat
48Using JFileChooser (1)
Getting an input file name using JFileChooser
JFileChooser chooser new JFileChooser() int
returnValue chooser.showOpenDialog(null) if
(returnValue JFileChooser.ERROR_OPTION
returnValue JFileChooser.CANCEL_OPTION)
// File was not chosen return File inFile
chooser.getSelectedFile()
See book-projects/chapter11/files/FileCopyChooser
49Using JFileChooser (2)
Getting an output file name using JFileChooser
JFileChooser chooser new JFileChooser() int
returnValue chooser.showSaveDialog(null) if
(returnValue JFileChooser.ERROR_OPTION
returnValue JFileChooser.CANCEL_OPTION )
// file was not chosen return File outFile
chooser.getSelectedFile()
See book-projects/chapter11/files/FileCopyChooser
50Reading a char stream (1)
Some methods from the Abstract Reader class
public abstract int read() throws
IOException public int read(char c) throws
IOException public int read(char c, int
startPos, int numChars) throws
IOException public void close() throws IOException
The single-char read method reads a char and
returns it as an integer. The return type cannot
be of type char since we need a sentinal value of
-1 to indicate end of file. The int type is
32-bits so there is lots of room for the values 0
to 65535 and the negative value -1.
51Reading a char stream (2)
Character at a time input model
FileReader in new FileReader("in.dat") int n
in.read() while (n ! -1) // process the char
value in n here n in.read() // and try to
read another char
More compact form
FileReader in new FileReader("in.dat") int
n while ( (n in.read()) ! -1) // process
the char value in n here
52Reading a char stream (3)
Buffered character at a time input model
BufferedReader in new BufferedReader(new
FileReader("in.dat")) int n while ( (n
in.read()) ! -1) // process the char
value in n here
There are actually two levels of buffering (1)
operating system buffers data from the disk (2)
buffered reader buffers the data from operating
system
53Reading a char stream (4)
Character array input model
BufferedReader in new BufferedReader(new
FileReader("in.dat")) char c new
char1024 int numChars while ( (numChars
in.read(c)) ! -1) // process c0 to
cnumChars - 1 here
Here the read method returns the number of
characters actually read or -1 if there are no
more characters (end of file)
54Reading a char stream (5)
BufferedReader has the following useful method
public String readLine() throws IOException
Line of characters at a time input model
BufferedReader in new BufferedReader(new
FileReader("in.dat")) String line while ( (line
in.readLine()) ! null ) // process the
line here
note that null, not -1 signals end of file
55Writing a char stream (1)
Some methods from the Abstract Writer class
public void write(int c) throws
IOException public abstract void write(char c,
int startPos, int numChars) throws
IOException public void write(char c) throws
IOException public void write(String s, int
startPos, int numChars) throws
IOException public void write(String s) throws
IOException public abstract void flush() throws
IOException public abstract void close() throws
IOException
56Writing a char stream (2)
Reading, processing, and writing single characters
BufferedReader in new BufferedReader(new
FileReader("in.dat")) BufferedWriter out
new BufferedWriter(new FileWriter("out.dat")) int
n while ( (n in.read()) ! -1 ) //
process char value in n here out.write(n) //
write it to the output file in.close() //
don't forget to close files out.close()
57Writing a char stream (3)
Reading, processing, and writing char arrays
BufferedReader in new BufferedReader(new
FileReader("in.dat")) BufferedWriter out
new BufferedWriter(new FileWriter("out.dat")) cha
r c new char1024 int numChars while (
(numChars in.read(c)) ! -1 ) // process
c0 to cnumChars - 1 here out.write(c, 0,
numChars) // write buffer to file in.close()
out.close()
58Writing a char stream (4)
Using a PrintWriter
Scanner console new Scanner(System.in) PrintWri
ter out new PrintWriter( new BufferedWriter(
new FileWriter("out.dat"))) System.out.println("W
hat is your name?") String name
console.nextLine() System.out.println("How old
are you?") int age console.nextInt() console.n
extLine() // eat end of line out.println(name)
out.println(age) out.close()
PrintWriter has the same print and println
methods that System.out has so you can use it to
write formatted text data to a character file.
59Connecting Output Streams
PrintWriter
Disk
Program
FileWriter
BufferedWriter
PrintWriter out new PrintWriter( new
BufferedWriter( new FileWriter(fileName))
)
60FileSearcher
Search a file for lines containing a given string
and write these lines to an output file
String line while ( (line in.readLine()) !
null ) if (line.indexOf(pattern) gt 0)
out.println(line) in.close() out.clo
se()
61FileSearcher class (1)
package chapter11.files import
java.io. public class FileSearcher File
inFile File outFile String pattern
public FileSearcher(File inFile, File
outFile, String pattern) this.inFile
inFile this.outFile outFile)
this.pattern pattern
62FileSearcher class (2)
public void searchFile() throws IOException
BufferedReader in new
BufferedReader( new FileReader(inFileNa
me)) PrintWriter out new
PrintWriter( new BufferedWriter(
new FileWriter(outFileName)))
String line while ( (line in.readLine()
! null) if (line.indexOf(pattern) gt
0) out.println(line)
in.close() out.close()
63FileSearcher class (3)
public static void main(String args)
if (args.length 3) File
inFile new File(args0) File outFile
new File(args1) FileSearcher
searcher new FileSearcher(inFile,
outFile, args2) searcher.searchFile()
else
System.out.println("args" inFileName ...")
// end of class
64Viewing a file as bytes
- Problem
- read a file
- convert each byte value to hex format
- display the results 16 bytes per line
65Algorithm (1)
BufferedInputStream in new
BufferedInputStream( new FileInputStream(inF
ile)) byte b new byte16 int
numBytes output.setText("") // output is a
TextArea while ( (numBytes in.read(b)) ! -1
) for (int k 0 k lt numBytes k)
output.append(byteToHex(bk) " "
output.append("\n") in.close()
66Algorithm (2)
the byteToHex method
private String byteToHex(byte b) int i b
0x000000FF String hex Integer.toHexString(i)
.toUpperCase() if (hex.length() 1)
hex "0" hex return hex
See ByteViewer GUI application in book-projects/ch
apter11/files
67ByteViewer GUI application
JFileChooser
Show bytes in a file in hexadecimal format
68ByteViewer class (1)
package chapter11.files import java.io. import
java.awt. import java.awt.event. import
javax.swing. import javax.swing.event. public
class ByteViewer extends JFrame private
JTextArea output private JFileChooser
chooser private String titleBar "Byte
Viewer"
69ByteViewer class (2)
public ByteViewer() setTitle(titleBar)
JButton view new JButton("Select file")
output new JTextArea(20,50)
output.setEditable(false)
output.setFont(new Font("Courier New",Font.BOLD,
14)) chooser new JFileChooser()
JPanel p new JPanel()
p.setLayout(new FlowLayout())
p.add(view) Container cp
getContentPane() cp.setLayout(new
BorderLayout()) cp.add(p,
BorderLayout.NORTH) cp.add(new
JScrollPane(output,BorderLayout.CENTER)
view.addActionListener(new ViewButtonHandler())
70ByteViewer class (3)
Inner class to handle the button press
private class ViewButtonHandler implements
ActionListener public void
actionPerformed(ActionEvent e)
viewFile()
71ByteViewer class (4)
Get the input file name using the JFileChooser
object
private void viewFile() int status
chooser.showOpenDialog(null) if (status
JFileChooser.ERROR_OPTION status
JFileChooser.CANCEL_OPTION)
return File inFile
chooser.getSelectedFile()
setTitle(titleBar " " inFile.getName()
"")
72ByteViewer class (5)
Read file 16 bytes at a time and display hex codes
BufferedInputStream in null try
in new BufferedInputStream(inFile))
byte b new byte16 int
numBytes output.setText("")
while ( (numBytes in.read(b)) ! -1)
for (int k 0 k lt numBytes k)
output.append(bytesToHex(bk) " ")
output.append("\n") in.close()
catch(IOException e)
e.printStackTrace() // end viewFile
73ByteViewer class (6)
Convert a byte value to hex format
private String byteToHex(byte b) int i
b 0x000000FF // cancel sign-extension
String hex Integer.toHexString().toUpperCase()
if (hex.length() 1) hex "0" hex
return hex
public static void main(String args)
ByteViewer viewer new ByteViewer()
viewer.pack() viewer.setVisible(true)
viewer.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE) // end of class
74Files of objects
- So far we have considered
- files of bytes (binary files)
- files of characters or lines (text files)
- It is also possible to design file structures to
represent higher level data structures such as
objects in two ways - text files where an object is represented by one
or more lines - binary files with an internal binary object format
75Text files of bank accounts
- File of multi-line records (3 lines per object)
- File of single line field separated records
123 Fred Jones 150.50
123Fred Jones150.50
colon separator
we will use this format
76Writing an account to a file
- Writing an account in single line format to a
file is easy if we use a PrintWriter - Assume out is a PrintWriter
- Assume a is a BankAccount object
out.println(a.getNumber() "" a.getName()
"" a.getBalance())
77Reading account from a file
- Reading lines with the single line colon
separated format seems to be harder - There is a standard class that is designed just
for this purpose - The StringTokenizer class can read lines whose
fields are separated by delimiters - It has a nextToken method that returns the next
field (token) each time it is called
78StringTokenizer
Constructor for a string tokenizer for a given
string and set of delimiters specified using a
string
public StringTokenizer(String s, String
delimiter)
Method for getting the next token. This method
throws a NoSuchElementException if there are no
more tokens. This is not a checked exception
public String nextToken()
79Using StringTokenizer
Algorithm for reading a line for a bank account
and tokenizing it. Assume in is a
BufferedReader. Here no error checking is done
String field1, field2, field3 String line
in.readLine() if (line null) return null //
end of file StringTokenizer t new
StringTokenizer(line, "") field1
t.nextToken() field2 t.nextToken() field3
t.nextToken() int number Integer.parseInt(field
1.trim()) double balance Double.parseDouble(fie
ld3.trim()) BankAccount b new
BankAccount(number,field2,balance)
80Extending BufferedReader
We can extend the BufferedReader class to include
the new readAccount method for reading bank
account objects
public class BufferedAccountReader extends
BufferedReader public BufferedAccountReader(R
eader in) ... public BufferedAccountReader
(Reader in, int size) ... public
BankAccount readAccount() throws
IOException, EOFException ...
81Extending PrintWriter
We can extend the PrintWriter class to include
the new writeAccount method for writing bank
account objects
public class PrintAccountWriter extends
PrintWriter public PrintAccountWriter(OutputS
tream out) ... public PrintAccountWriter(Writ
er out) ... public PrintAccountWriter(OutputS
tream out, boolean autoFlush) ...
public PrintAccountWriter(Writer out,
boolean autoFlush( ... public void
writeAccount(BankAccount a) ...
82BufferedAccountReader (1)
import java.io. import java.util.StringTokenizer
import java.util.NoSuchElementException public
class BufferedAccountReader extends
BufferedReader public BufferedAccountReader(R
eader in) super(in) public
BufferedAccountReader(Reader in, int size)
super(in, size)
83BufferedAccountReader (2)
public BankAccount readAccount() throws
IOException, EOFException int number
0 double balance 0.0 String
field1, field2, field3
Read a line from the file (note that we use the
"this" object since we are extending
BufferedReader which has the readLine method in
it.
String line readLine() // this object
If we are at end of file signal it by returning
null account
if (line null) return null
84BufferedAccountReader (3)
Construct tokenizer and try to read three tokens
from line. Note if we get a partial record then
we treat this as end of file and throw an
EOFException
StringTokenizer t new
StringTokenizer(line, "") try
field1 t.nextToken() field2
t.nextToken() field3 t.nextToken()
catch (NoSuchElementException e)
throw new EOFException("Partial
record")
85BufferedAccountReader (4)
Now check the account number field and throw a
NumberFormat exception with our own custom error
message if it is not a valid integer
try number
Integer.parseInt(field1.trim())
catch (NumberFormatException e)
throw new NumberFormatException(
"Invalid account number")
86BufferedAccountReader (5)
Now check the account balance field and throw a
NumberFormat exception with our own custom error
message if it is not a valid double
try balance Double.parseInt(field
3.trim()) catch (NumberFormatExcept
ion e) throw new NumberFormatException(
"Invalid bank balance")
return new BankAccount(number, field2.trim(),
balance) // end readAccount // end
class
87PrintAccountWriter (1)
import java.io. public class PrintAccountWriter
extends PrintWriter public
PrintAccountWriter(OutputStream out)
super(out) public PrintAccountWriter(Writer
out) super(out) public
PrintAccountWriter(OutputStream out,
boolean autoFlush) super(out, autoFlush)
public PrintAccountWriter(Writer out,
boolean autoFlush) super(out, autoFlush)
88PrintAccountWriter (2)
Write a line to the file (note that we use the
"this" object since we are extending PrintWriter
which has the print and println methods in it.
public void writeAccount(BankAccount a)
this.println(a.getNumber() ""
a.getName() "" a.getBalance()) //
end class
89Test file accounts.txt
A sample text file
139952707Cecil Patterson22158.11 105870087Woody
Adamson797.71 201756613David
Irving941.38 643908962Gerry Laforge63606.09 442
753562Mary Lavigne34434.45 218560951Mike
Tessier70366.62 969167302Dave
Jenkins899.24 670350355Carol Schwartz5643.45 70
7959408Kim Flintstone15418.01 176306464Bob
Stevenson5921.03
90Processing account file (1)
Read lines of an account file with a while loop
BufferedAccountReader in new
BufferedAccountReader( new
FileReader(inFileName)) BankAccount a
in.readAccount() while (a ! null) //
process account here a in.readAccount() //
read next account in.close()
91Processing account file (2)
Compact form using while loop
BufferedAccountReader in new
BufferedAccountReader( new
FileReader(inFileName)) BankAccount a while (
(a in.readAccount()) ! null ) // process
account here in.close()
92Processing account file (3)
Displaying account file in terminal window
BufferedAccountReader in new
BufferedAccountReader( new
FileReader(inFileName)) PrintAccountWriter out
new PrintAccountWriter(System.out) BankAcco
unt a while ( (a in.readAccount()) ! null
) out.writeAccount(a) in.close()
out.close()
for terminal output
93Processing account file (4)
Copying an account file
BufferedAccountReader in new
BufferedAccountReader( new
FileReader(inFileName)) PrintAccountWriter out
new PrintAccountWriter( new
BufferedWriter(new FileWriter(outFileName))) Ban
kAccount a while ( (a in.readAccount()) !
null ) out.writeAccount(a) in.close()
out.close()
94Processing account file (5)
Finding account with maximum balance
BufferedAccountReader in new
BufferedAccountReader( new
FileReader(inFileName)) BankAccount a
in.readAccount() double maxBalance
a.getBalance() while (a! null) if
(a.getBalance() gt maxBalance) maxBalance
a.getBalance() a in.readAccount() in.clos
e()
95Processing account file (6)
Write a file of accounts with balance lt 1000
BufferedAccountReader in new
BufferedAccountReader( new
FileReader(inFileName)) PrintAccountWriter out
new PrintAccountWriter( new
BufferedWriter(new FileWriter(outFileName))) Ban
kAccount a in.readAccount() while (a !
null) if (a.getBalance() lt 1000.0)
out.writeAccount(a) in.readAccount() in.clo
se() out.close()
96MaxBalanceCalculator class (1)
import java.io. public class MaxBalanceCalculato
r private File inFile public
MaxBalanceCalculator(File inFile)
this.inFile inFile public void
findMaxBalance() throws FileNotFoundExceptio
n, IOException BufferedAccountReader
in null try in new
BufferedAccountReader( new
FileReader(inFile))
97MaxBalanceCalculator class (2)
BankAccount a in.readAccount()
double maxBalance a.getBalance()
while (a ! null) if (a.getBalance()
gt maxBalance) maxBalance
a.getBalance() a
in.readAccount()
in.close() System.out.println("Max
balance is " maxBalance)
// end of try finally if (in !
null) in.close() // end
findMaxBalance
98MaxBalanceCalculator class (3)
public static void main(String args) throws
FileNotFoundException, IOException
if (args.length 1) File
inFile new File(args0)
MaxBalanceCalculator calc new
MaxBalanceCalculator(inFile)
calc.findMaxBalance() else
System.out.println("args
inFileName) // end class
99Under1000Processor
BufferedAccountReader in new
BufferedAccountReader( new
FileReader(inFile)) PrintAccountWriter out
new PrintAccountWriter(
new BufferedWriter( new
FileWriter(outFile))) BankAccount a
in.readAccount() while (a ! null) if
(a.getBalance() lt 1000.0)
out.writeAccount(a) a
in.readAccount() in.close() out.close()
100Sequential processing
- So far we have done only sequential processing of
files - finding account with maximum balance
- Finding accounts with balances less than 1000
- This means we only need to read one account at a
time - Some problems require that all accounts be
available at once (requires an array) - sorting a file in increasing account order
101Reading into arrays
Read account file into an array and process it
using the array
BufferedAccountReader in new
BufferedAccountReader(new FileReader(inFileName))
BankAccount accounts new BankAccount1000 B
ankAccount b int index 0 while( (b
in.readAccount()) ! null) accountsindex
b index index 1 int numAccounts
index in.close() for (int k 0 k lt
numAccounts k) // process accounts here
this is a problem if there are more than 1000
accounts in file
102Dynamic arrays
- The array data type in Java is not dynamic
- This means that once an array of a certain size
has been constructed and it becomes full then no
more elements can be put into the array - The ArrayList class is a container class for
objects that is part of the Java collections
library that is dynamic and implements the List
interface
103ArrayListltEgt class (1)
Constructor for a list fo elements of type E
public ArrayList()
Another form of the constructor
public ArrayList(int initialSize)
add element to end of list
public void add(E element)
Return object at position i
public E get(int i)
Replace object at position i by a new one
public void set(int i, E element)
104ArrayListltEgt class (2)
Return number of elements currently in the list
public int size()
Test for an empty list (returns true if list is
empty)
public boolean isEmpty()
There are many other methods
105ArrayListltEgt class (3)
Construct a list that initially has space for
1000 elements of type BankAccount
ListltBankAccountgt accounts new
ArrayListltBankAccountgt(1000)
Add an account b to the end of the list
accounts.add(b)
Get the account in the list at position k.
BankAccount b accounts.get(k)
Return the current size of the list
int numAccounts accounts.size()
106Reading and processing a list
Read accounts from file into a list
BufferedAccountReader in new
BufferedAccountReader(new FileReader(inFileName))
ListltBankAccountgt accounts new
ArrayListltBankAccountgt(100) BankAccount b while
( (b in.readAccount()) ! null )
accounts.add(b)
Process the list of accounts
for (int k 0 k lt accounts.size() k)
BankAccount b accounts.get(k) // process
account b here
107ListProcessor example (1)
Read file of accounts into an ArrayList and sort
package chapter11.bakn_account import
custom_classes.BankAccount import
java.io. import java.util.List import
java.util.ArrayList public class
ListProcessor private File inFile
public ListProcessor(File inFile)
this.inFile inFile
108ListProcessor example (2)
Process the list
public void processList() throws
FileNotFoundException, IOException
ListltBankAccountgt accounts new
ArrayListltBankAccountgt()
BufferedAccountReader in null
PrintAccountWriter out null try
in new BufferdAccountReader(
new FileReader(inFile)
109ListProcessor example (3)
Read list into an ArrayList object
BankAccount b while ( (b
in.readAccount())! null)
accounts.add(b)
110ListProcessor example (4)
sort the list and write it to standard output
bubbleSort(accounts) out new
PrintAccountWriter(System.out) for (int
k 0 k lt accounts.size() k)
out.writeAccount(accounts.get(k))
// end of try block finally
if (in ! null) in.close()
if (out ! null) out.close() // end
of processList method
111BubbleSort from Chapter 8
public void bubbleSort(double a) int n
a.length for (int p 1 p lt n - 1
p) for (int j 0 j lt
n-1-p j) if (aj gt
aj 1) double
temp aj aj aj 1
aj 1 temp
We need to modify this to use an
ArrayList instead of a double array
112BubbleSort for List
public void bubbleSort(ListltBankAccountgt a)
int n a.size() for (int p 1 p lt n
- 1 p) for (int j 0 j lt n-1-p
j) String name1
a.get(j).getName() String name2
a.get(j1).getName() if
(name1.compareTo(name2) gt 0)
BankAccount temp a.get(j)
a.set(j, a.get(j1)) a.set(j 1,
temp)
113ListProcessor example (5)
main method
public static void main(String args)
throws FileNotFoundException, IOException
if (args.length 1) File
inFile new File(args0)
ListProcessor processor new
ListProcessor(inFile)
processor.processList() else
System.out.println("args inFileName")
// end of class
114Binary object files
- We have two bank account classes. The base class,
BankAccount, and the subclass JointBankAccount. - We would need a format such as
- with a first field to indicate the type of
account. We can do better with binary object
files and serialization
112121212Fred Jones134.56 222323232Mary
BrownBob Brown4567.23
115Object serialization (1)
- The objects in any hierarchy can be written to
disk in an internal format. - All data fields are written to disk.
- If these data fields reference other objects then
they are written to disk too. - This is called object serialization and means
that all data necessary to reconstruct the object
is written to disk.
116Object serialization (2)
- To indicate that you want a classes objects to be
serializable it's necessary to implement the
Serializable interface in package java.io - This interface contains no methods and simply
means - "you have the right to serialize my objects"
- These rights are automatically granted to all
subclasses
117BankAccount serialization
- Example BankAccount
- Since JointBankAccount is a subclass its objects
will automatically be serialized.
public class BankAccount implements
java.io.Serializable private static final
long serialVersionUID 3616750539038917338
L // everything else here is same as before
118ObjectOutputStream (1)
Constructor for an object output stream
public ObjectOutputStream(OutputStream out)
throws IOException
Connecting an ObjectOutputStream object to a file
ObjectOutputStream out new ObjectOutputStream(
new FileOutputStream(outFileName))
Method to write an object to an object output
stream
public void writeObject(Object obj) throws
IOException
119ObjectOutputStream (2)
Writing an ArrayList object called accounts to a
binary object file Make some account objects and
store them in an ArrayList object
ListltBankAccount accounts new
ArrayListltBankAccountgt() accounts.add( new
BankAccount(123,"Fred",345.50)) accounts.add(
new JointBankAccount(345, "Jack", "Jill", 450))
Write the ArrayList object to a binary object file
ObjectOutputStream out new ObjectOutputStream(
new FileOutputStream(outFileName)) out.writeObj
ect(accounts) out.close()
120AccountListObjectWriter (1)
package chapter11.bank_account import
custom_classes.BankAccount import
custom_classes.JointBankAccountl import
java.io.IOException import java.io.ObjectOutputSt
ream import java.io.FileOutputStream import
java.util.ArrayList import java.util.List publi
c class AccountListObjectWriter private File
outFile private ListltBankAccountgt accounts
121AccountListObjectWriter (2)
Construct an ArrayList of accounts
public AccountListObjectWriter( File
outFile) this.outFile outFile
accounts new ArrayListltBankAccountgt()
accounts.add(new BankAccount(...))
accounts.add(new BankAccount(...))
accounts.add(new JointBankAccount(...))
...
122AccountListObjectWriter (3)
Write the ArrayList object to binary object file
public void writeAccountList() throws
IOException ObjectOutputStream out
null try out new
ObjectOutputStream( new
FileOutputStream(outFile))
out.writeObject(accounts) out.close()
finally if (out ! null)
out.close()
123AccountListObjectWriter (4)
public static void main(String args) throws
IOException if (args.length
1) File outFile new
File(args0) AccountListObjectWriter
writer new AccountListObjectWriter(o
utFile) writer.writeAccountList()
else System.out.println(
"args outFileName") // end class
124ObjectInputStream (1)
Constructor for an object input stream
public ObjectInputStream(InputStream out) throws
IOException
Connecting an ObjectInputStream object to a file
ObjectInputStream in new ObjectInputStream(
new FileInputStream(inFileName))
Method to read (deserialize) an object from an
object input stream
public Object readObject() throws
ClassNotFoundException, IOException
125ObjectInputStream (2)
Reading an ArrayList object called accounts from
a binary object file
ObjectInputStream in new ObjectInputStream(
new FileInputStream(inFileName)) ListltBankAccount
gt accounts (ListltBankAccountgt)
in.readObject() in.close()
126AccountListObjectReader (1)
package chapter11.bank_account import
custom_classes BankAccount import
java.io. import java.util.ArrayList import
java.util.List public class AccountListObjectRea
der private File inFile public
AccountListObjectReader( String inFile)
this.inFile inFile
127AccountListObjectReader (2)
Read an ArrayList object from a binary object file
public void processAccountList() throws
ClassNotFoundException,
FileNotFoundException, IOException
ObjectInputSteam in null try
in new ObjectInputStream(
new FileInputStream(inFileName))
ListltBankAccountgt accounts (List)
in.readObject() in.close()
128AccountListObjectReader (3)
Compute the total balance in the accounts
double totalBalance 0.0 for
(int k 0 k lt accounts.size k)
BankAccount b accounts.get(k)
totalBalance b.getBalance()
System.out.println(b)
System.out.println(totalBalance) // end
try block
129AccountListObjectReader (4)
Check if file was closed
finally if (in ! null)
in.close() // end
processAccountList
130AccountListObjectReader (5)
public static void main(String args) throws
ClassNotFoundException,
FileNotFoundException, IOException if
(args.length 1) File inFile
new File(args0) AccountListObjectReade
r reader new AccountListObjectReader
(inFile) reader.processAccountList()
else
System.println("args inFileName")
// end class
131End of File
- How do we indicate EOF when reading a binary
object stream? - we cannot use a null return value from the
readObject method since null is a perfectly
acceptable object value that can be stored in a
binary object file. - An EOFException is thrown at end of file and is
used to determine when to stop reading.
132Reading multiple objects
try while (true) // its not really an infinite
loop // use in.readObject() here to return
next object catch (EOFException e) //
nothing to do here, normal end of file catch
(ClassNotFoundException e) // display message
here finally if (in ! null) in.close()
// may throw IOException
NEW finally block will always be executed
whether or not an exception occurs
133Use ArrayList
- Reading multiple objects from a binary object
file created by writeObject is complicated - If you have multiple objects its better to put
them in an ArrayList, write the list to the file
and then readObject can just read one object from
the file - You can then extract your objects as elements in
the ArrayList object