Transcript Document

Introduction
• Files
– Long-term storage of large amounts of data
– Persistent data exists after termination of program
– Files stored on secondary storage devices
• Magnetic disks
• Optical disks
• Magnetic tapes
– Sequential and random access files
Data Hierarchy
• Smallest data item in a computer is a bit
– Bit can be either 0 or 1
– Bit short for “binary digit”
• Programmers work with higher level data items
–
–
–
–
Decimal digits: (0-9)
Letters: (A-Z and a-z)
Special symbols: (e.g., $, @, %, &, *, (, ), -, +, “, :, ?, /, etc.)
Java uses Unicode characters composed of 2 bytes
• A byte is normally 8 bits long
• Fields (Java instance variables)
– Composed of characters or bytes
– Conveys meaning
Data Hierarchy
• Data hierarchy
– Data items in a computer form a hierarchy
• Progresses from bits, to characters, to fields, etc.
• Records
– Composed of several fields
– Implemented as a class in Java
– See the figure on the next slide for example
• File is a group of related records
– One field in each record is a record key
• Record key is a unique identifier for a record
– Sequential file
• Records stored in order by record key
The data hierarchy.
Files and Streams
• Java views a file as a stream of bytes
– File ends with end-of-file marker or a specific byte number
– File as a stream of bytes associated with an object
• Java also associates streams with devices
– System.in, System.out, and System.err
– Streams can be redirected
• File processing with classes in package java.io
–
–
–
–
FileInputStream for byte-based input from a file
FileOutputStream for byte-based output to a file
FileReader for character-based input from a file
FileWriter for character-based output to a file
Java’s view of a file of n bytes.
Files and Streams
• Buffering
– Improves performance of I/O
– Copies each output to a region of memory called a buffer
– Entire buffer output to disk at once
• One long disk access takes less time than many smaller ones
– A program can convert a unbuffered stream into a buffered
stream using the wrapping idiom
• Example
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new
FileWriter("characteroutput.txt"));
A portion of the class hierarchy of the
java.io package.
A portion of the class hierarchy of the java.io package
java.lang.Object
File
FileDescriptor
InputStream
ByteArrayInputStream
FileInputStream
FilterInputStream
BufferedInputStream
DataInputStream
PushbackInputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
OutputStream
ByteArrayOutputStream
FileOutputStream
FilterOutputStream
BufferedOutputStream
DataOutputStream
PrintStream
ObjectOutputStream
PipedOutputStream
A portion of the class hierarchy of the
java.io package (cont.).
RandomAccessFile
Reader
BufferedReader
LineNumberReader
CharArrayReader
FilterReader
PushbackReader
InputStreamReader
FileReader
PipedReader
StringReader
Writer
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
FileWriter
PipedWriter
PrintWriter
StringWriter
import java.util.StringTokenizer;
Example: reading a text file
import java.io.*;
import java.text.DecimalFormat;
class InventoryItem {
private String name;
private int units;
// number of available units of this item
private float price; // price per unit of this item
private DecimalFormat fmt;
public InventoryItem (String itemName, int numUnits, float cost) {
name = itemName;
units = numUnits;
price = cost;
fmt = new DecimalFormat ("0.##");
}
public String toString()
{
return name + ":\t" + units + " at " + price + " = " +
fmt.format ((units * price));
}
}
public class Inventory{
// Reads data about a store inventory from an input file,
// creating an array of InventoryItem objects, then prints them.
public static void main (String[] args)
{
final int MAX = 100;
InventoryItem[] items = new InventoryItem[MAX];
StringTokenizer tokenizer;
String line, name, file="inventory.txt";
int units, count = 0;
float price;
Example: reading a text file
try{
FileReader fr = new FileReader (file);
BufferedReader inFile = new BufferedReader (fr);
line = inFile.readLine();
while (line != null) {
tokenizer = new StringTokenizer (line);
name = tokenizer.nextToken();
try
{
units = Integer.parseInt (tokenizer.nextToken());
price = Float.parseFloat (tokenizer.nextToken());
items[count++] = new InventoryItem (name, units, price);
}
catch (NumberFormatException exception)
{
System.out.println ("Error in input. Line ignored:");
System.out.println (line);
}
line = inFile.readLine();
}
inFile.close();
Example: reading a text file
for (int scan = 0; scan < count; scan++)
System.out.println (items[scan]);
}
catch (FileNotFoundException exception)
{
System.out.println ("The file " + file + " was not found.");
}
catch (IOException exception)
{
System.out.println (exception);
}
}
}
import java.io.*;
Example: writing a text file
public class TestData {
// Creates a file of test data that consists of ten lines each
// containing ten integer values in the range 0 to 99.
public static void main (String[] args) throws IOException
{
final int MAX = 10;
int value;
String file = "test.txt";
FileWriter fw = new FileWriter (file);
BufferedWriter bw = new BufferedWriter (fw);
PrintWriter outFile = new PrintWriter (bw);
for (int line=1; line <= MAX; line++)
{
for (int num=1; num <= MAX; num++)
{
value = (int) (Math.random() * 100);
outFile.print (value + "
");
}
outFile.println ();
}
outFile.close();
System.out.println ("Output file has been created: " + file);
}
}
Data Streams and Object Streams
• Data streams support I/O of primitive data types
• Object streams support I/O of objects
• Most, but not all, standard classes support
serialization of their objects.
– Those classes implement the marker interface
Serializable
– Every instance variable of the class should is a
Serializable
• Object stream classes
– ObjectInputStream and ObjectOutputStream
• Output using the writeObject() method
Updating Sequential-Access File
• Difficult to update a sequential-access file
– Entire file must be rewritten to change one field
– Only acceptable if many records being updated at once
Random-Access File
• “Instant-access” applications
– Record must be located immediately
– Transaction-processing systems require rapid access
• Random-access files
– behave like a large array of bytes stored in the file system
– Access individual records directly and quickly
– Use fixed length for every record
• Easy to calculate record locations
– Insert records without destroying other data in file
– Figure on the next slide shows random-access file
Java’s view of a random-access file
Random-Access File
• RandomAccessFile objects
– Like DataInputStream and DataOutputstream
– Reads or writes data in spot specified by file-position pointer
• Manipulates all data as primitive types
• Normally writes one object at a time to file
// Record class for the RandomAccessFile programs.
import java.io.*;
public class Record {
private int account;
private String lastName;
private String firstName;
private double balance;
public Record(int a, String f, String l, double b) {
account=a;
firstName=f;
lastName=l;
balance=b;
}
public Record() {
account=0;
firstName=null;
lastName=null;
balance=0;
}
// Read a record from the specified RandomAccessFile
public void read( RandomAccessFile file ) throws IOException
account = file.readInt();
byte b1[] = new byte[ 15 ];
file.readFully( b1 );
firstName = new String( b1 );
firstName=firstName.trim();
byte b2[] = new byte[ 15 ];
file.readFully( b2 );
lastName = new String( b2 );
lastName=lastName.trim();
balance = file.readDouble();
}
Defining a class to be
used for reading and
writing records to a
random access file
{
// Write a record to the specified RandomAccessFile
public void write( RandomAccessFile file ) throws IOException
{
file.writeInt( account );
byte b1[] = new byte[ 15 ];
if ( firstName != null )
b1 = firstName.getBytes();
file.write( b1 );
byte b2[] = new byte[ 15 ];
if ( lastName != null )
b2 = lastName.getBytes();
file.write( b2 );
file.writeDouble( balance );
}
public int getAccount(){ return account;}
public String getlName(){ return lastName;}
public String getfName(){ return firstName;}
public double getBalance(){ return balance;}
// NOTE: This method contains a hard coded value for the size of a
// record of information.
public int size() { return 42; }
}
import java.io.*;
public class CreateRandFile {
private Record blank;
RandomAccessFile file;
public CreateRandFile()
{
blank = new Record();
try {
file = new RandomAccessFile( "credit.dat", "rw" );
}
catch( IOException e ) {
System.err.println( "File not opened properly\n" +
e.toString() );
System.exit( 1 );
}
}
public void create()
{
try {
for ( int i = 0; i < 100; i++ )
blank.write( file );
}
catch ( IOException e ) {
System.err.println( e.toString() );
}
}
public static void main( String args[] )
{
CreateRandFile accounts = new CreateRandFile();
accounts.create();
}
}
This program creates
a random access file
sequentially by
writing 100 empty
records to disk.
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class WriteRandFile extends JFrame {
// Application window components
JTextField acct,
// where user enters account number
fName,
// where user enters first name
lName,
// where user enters last name
bal;
// where user enters balance
JButton enter,
// send record to file
done;
// quit program
JLabel acctLabel,
// account label
fNameLabel,
// first name label
lNameLabel,
// last name label
balLabel;
// balance label
RandomAccessFile output;
Record data;
// file for output
public WriteRandFile()
{
super( "Write to random access file" );
data = new Record();
try {
output = new RandomAccessFile( "credit.dat", "rw" );
}
catch ( IOException e ) {
System.err.println( e.toString() );
System.exit( 1 );
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
Container c = getContentPane();
c.setLayout( new GridLayout( 5, 2 ) );
acct = new JTextField( 20 );
acctLabel = new JLabel( "Account Number" );
fName = new JTextField( 20 );
fNameLabel = new JLabel( "First Name" );
lName = new JTextField( 20 );
lNameLabel = new JLabel( "Last Name" );
bal = new JTextField( 20 );
balLabel = new JLabel( "Balance" );
enter = new JButton( "Enter" );
done = new JButton( "Done" );
c.add( acctLabel );
// add label
c.add( acct );
// add TextField
c.add( fNameLabel ); // add label
c.add( fName );
// add TextField
c.add( lNameLabel ); // add label
c.add( lName );
// add TextField
c.add( balLabel );
// add label
c.add( bal );
// add TextField
c.add( enter );
// add button
c.add( done );
// add button
done.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
cleanup(); // write data, close file, etc.
setVisible(false);
dispose(); // release system resources
System.exit( 0 );
} }
);
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
enter.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
addRecord();
} }
);
setSize( 300, 150 );
setVisible( true );
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
public void addRecord()
{
int acctNum = 0;
Double d;
acctNum = ( new Integer( acct.getText() ) ).intValue();
// output the values to the file
try {
if ( acctNum > 0 && acctNum <= 100 ) {
String f=fName.getText();
String l=lName.getText();
double b=Double.parseDouble(bal.getText());
data = new Record(acctNum,f,l,b);
output.seek( (long) ( acctNum-1 ) * data.size() );
data.write( output );
// clear the TextFields
acct.setText( "" );
fName.setText( "" );
lName.setText( "" );
bal.setText( "" );
}
else {
acct.setText( "Enter valid account (1-100)" );
acct.selectAll();
}
}
catch ( IOException e ) {
System.err.println( "Error during write to file\n" +
e.toString() );
System.exit( 1 );
}
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
seek method of
RandomAccessFile:
sets file-position
pointer to a specific
point in file
public void cleanup()
{
if ( !acct.getText().equals("") )
addRecord();
try {
output.close();
}
catch ( IOException e ) {
System.err.println( "File not closed properly\n" +
e.toString() );
System.exit( 1 );
}
}
public static void main( String args[] )
{
WriteRandFile accounts = new WriteRandFile();
}
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ReadRandFile extends JFrame {
// Application window components
JTextField acct,
// where user enters account number
fName,
// where user enters first name
lName,
// where user enters last name
bal;
// where user enters balance
JButton next,
// send record to file
done;
// quit program
JLabel acctLabel,
// account label
fNameLabel,
// first name label
lNameLabel,
// last name label
balLabel;
// balance label
RandomAccessFile input; // file for output
Record data;
boolean moreRecords=true;
public ReadRandFile()
{
super( "Write to random access file" );
data = new Record();
try {
input = new RandomAccessFile( "credit.dat", "r" );
}
catch ( IOException e ) {
System.err.println( e.toString() );
System.exit( 1 );
}
This program opens a
random-access file
and displays only the
records with data.
Container c = getContentPane();
c.setLayout( new GridLayout( 5, 2 ) );
acct = new JTextField( 20 );
acctLabel = new JLabel( "Account Number" );
fName = new JTextField( 20 );
fNameLabel = new JLabel( "First Name" );
lName = new JTextField( 20 );
lNameLabel = new JLabel( "Last Name" );
bal = new JTextField( 20 );
balLabel = new JLabel( "Balance" );
next = new JButton( "Next" );
done = new JButton( "Done" );
c.add( acctLabel );
// add label
c.add( acct );
// add TextField
c.add( fNameLabel ); // add label
c.add( fName );
// add TextField
c.add( lNameLabel ); // add label
c.add( lName );
// add TextField
c.add( balLabel );
// add label
c.add( bal );
// add TextField
c.add( next );
// add button
c.add( done );
// add button
This program opens a
random-access file
and displays only the
records with data.
done.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
cleanup(); // write data, close file, etc.
setVisible(false)();
dispose(); // release system resources
System.exit( 0 );
} }
);
next.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
readRecord();
} }
);
setSize( 300, 150 );
setVisible( true );
}
This program opens a
random-access file
and displays only the
records with data.
public void readRecord()
{
try {
do { // loop over empty records
data.read( input );
} while ( input.getFilePointer() < input.length() &&
data.getAccount() == 0 );
}
catch( IOException e ) {
moreRecords = false;
}
// transfer full record data into textfields
if ( data.getAccount() != 0 ) {
acct.setText( String.valueOf( data.getAccount() ) );
String fN=data.getfName();
fName.setText( fN);
String lN=data.getlName();
lName.setText( lN );
bal.setText( String.valueOf( data.getBalance() ) );
}
}
This program opens a
random-access file
and displays only the
records with data.
public void cleanup()
{
try {
input.close();
}
catch ( IOException e ) {
System.err.println( e.toString() );
System.exit( 1 );
}
}
public static void main( String args[] )
{
ReadRandFile accounts = new ReadRandFile();
}
}
This program opens a
random-access file
and displays only the
records with data.
Application: Transaction Processing
• Substantial transaction-processing system
– Uses random-access file
– Updates, adds and deletes accounts