Transcript Lecture 11

CS 116
Object Oriented
Programming II
Lecture 11
Acknowledgement: Contains materials provided by George Koutsogiannakis and Matt Bauer
Today’s Topics
• The java.io Package
• Reading Text Files
• Reading Structured Text Files
• Reading files using Input Streams
2
File Types
• Java basically supports two types of files:
• Text files (human readable): data is stored as characters
• Binary files: data is stored as raw bytes (1s and 0s)
• E.g. executable files, image files
• The type of a file determines the Java API classes for
writing to the file.
• Input to the file can be:
• Files written using Bytes Streams (1s and 0s).
• Files written using Character Streams (char types).
• Files written in terms of Strings (text).
3
File Types
• Input to the file can be: (cont.)
• Files written using primitive data types (int, double etc)
• Files written using entire object streams (recording all
information about an object in a coded format).
• To read an existing file, you must know the file's
type in order to select and import the appropriate
library classes for reading the file.
4
Reading Text Files with Scanner
import java.io.File;
catch)(IOException ioe){
import java.io.IOException;
import java.util.Scanner;
Public class ReadFile {
Public static void main(String[] args) {
System.out.println(ioe.t
oString()); }
}
}
try{
File myfile=new File(“mytextfiel.txt”);
Scanner scan=new Scanner(myfile);
while(scan.hasMoreTokens()) {
• Text files are human readable
• Lines of tokens separated by a
delimiter (default delimiter:
space)
String str=scan.next();
System.out.println(str);
}
5
Streams
• File writing and reading is accomplished with streams.
• There are input and output streams
• The term input means input to your program or consul
from a file.
• The term output means from your program or consul to
a file .
• Therefore:
• To read a file input stream is needed.
• To write to a file output stream is needed.
• The java.io package provides the classes for establishing
input and output streams.
6
Hierarchy for Input Classes
Java classes to read files
using streams
7
Selected Input Classes in the java.io Package
Class
Description
InputStream
Abstract superclass representing a
stream of raw bytes
Input stream to read raw bytes of data
from files
FileInputStream
ObjectInputStream
Class to read/recover objects from a
file written using ObjectOutputStream
8
FileInputStream Class
Use the read() method to
read a fixed number of
bytes
• FileInputStream Class reads the file byte by byte
• Different from scanner – scanner reads token by token
Import java.io.*;
try {
//Reading a file (even text file) as a sequence of bytes
FileInputStream fileInputStream = new FileInputStream(“input.txt");
byte[] arr = new byte[1024];
int actualBytesRead = fileInputStream.read(arr, 0, arr.length);
}catch(IOException e){
e.printStackTrace();
}
BufferedReader Class
• FileInputStream when used with other Stream
classes can be very powerful
• Example: using BufferedReader Class with the
FileInputStream class
• Read from character-input stream
• Converts the input produced by FileInputStream class to
human readable form
• “Buffers” a sequence of characters
Reading using Streams (Example:
Reading one character at a time)
try{
FileInputStream file=new FileInputStream(“input.txt");
BufferedReader filereader=new BufferedReader(new InputStreamReader(file));
int index=0;
int count=0;
while(index>=0) {
Use BufferefReader with the
FileInputStream class
count++; //count the no. of characters in the file
index=filereader.read();
}
• Use the read() method to
filereader.close();
read one character at a
file.close();
time. Check out the API for
other methods in this
}// end of try; use a catch block with the IOException class
class.
11
Reading using Streams (Example:
Reading one character at a time)
try{
• To convert input
stream to character
stream
FileInputStream file=new FileInputStream(“input.txt");
BufferedReader filereader=new BufferedReader(new InputStreamReader(file));
int index=0;
int count=0;
while(index>=0) {
Use BufferefReader with the
FileInputStream class
count++; //count the no. of characters in the file
index=filereader.read();
}
• Use the read() method to
filereader.close();
read one character at a
file.close();
time. Check out the API for
other methods in this
}// end of try; use a catch block with the IOException class
class.
12
Example Reading Text File
• In this example a buffer stream was used.
• The buffer stream wraps the File Stream.
• The while loop and when we encounter -1, since this is the indicator that the end of a file
has been reached (-1 is added to the end of the file when we create the file).
• Calling the read method of InputStreamReader class returns an int .If the end of the file is
reached the value of the int is -1. The method reads one character at a time.
• In this example we are not saving what we read. The count counts the number of readings
made in order to possibly create an array.
• We can repeat the loop once we have created an array and this time save the readings
into the array by using a different format of the read method:
int index=filereader.read(myarray, 0, count-1);
this call places the readings into the array, where array is an array of char data types
(from 0th index to the last index).
13
Example Reading Text File
• The char array myarray, needs to be instantiated to the correct size before it is
used in a while loop to capture the characters read. Therefore we need to loop
twice through the file.
• The first time to capture the count of characters. We
use the value of count to set the size of the char array.
Close the stream objects used!!!
• The second time we create a new set of stream objects
and we loop again through the file , this time using the
read method that takes the char array as argument.
• Keep in mind that an array of char types (myarray) can be converted to a String
by using: String str=new String(myarray);
14
Opening and Closing an Input Stream
• When we construct an input stream or output stream object, the JVM
associates the file name, standard input stream, or standard output
stream with our object. This is opening the file.
• When we are finished with a file, we optionally call the close method to
release the resources associated with the file.
Return value
Method name and argument list
void
close( )
releases resources associated with an
open input stream. Throws an IOException.
Reading Structured Text Files
• Some text files are organized into lines that
represent a record -- a set of data values containing
information about an item.
• The data values are separated by one or more
delimiters; that is, a special character or characters
that separate one value from the next.
• As we read the file, we need to parse each line;
that is, separate the line into the individual data
values called tokens.
16
Reading Structured Text Files
(Example: Airline records)
• An airline company could store data in a file where each line represents a flight
segment containing the following data:
•
•
•
•
•
flight number
origin airport
destination airport
number of passengers
average ticket price
• These are called headers or field names of the record.
• Such a file could contain the following data:
AA123,BWI,SFO,235,239.5
AA200,BOS,JFK,150,89.3
…
• In this case, the delimiter is a comma. This example shows two records (or two rows
of data).
17
Remember the StringTokenizer
Class/Split method in String class?
• The StringTokenizer class is designed to parse
Strings into tokens.
• StringTokenizer is in the java.util package.
• When we construct a StringTokenizer object, we
specify the delimiters that separate the data we
want to tokenize.
• Can we use the scanner class to achieve this?
• Check out the constructors of the scanner class.
• We used scanner to read from a file. Can it “read” a
string?
18
Reading Structured Text Files
(Example: Airline records)
try{
Use another scanner
object to read and
parse each line
Scanner file = new Scanner( new File( "flights.txt" ) );
while ( file.hasNext( ) ) // test for the end of the file
{
String stringRead = file.nextLine( ); // read a line
Scanner parse = new Scanner( stringRead ); //
process the line read
parse.useDelimiter( "," );
String flightNumber = parse.next( );
String origin = parse.next( );
String destination = parse.next( );
//code to process these tokens (origin, destination, etc)
}
}//use a catch black
In class Exercise
• Can you read structure files using the
BufferedReader class?
• Try it with the airline example
• Do the following:
• Create a text file called “input.txt” with data with the
following structure
AA123,BWI,SFO,235,239.5
AA200,BOS,JFK,150,89.3
….
• Write a client class that uses the BufferedReader class to reads
the file line by line
• The client will print out the following output.
In class Exercise
Sample output:
Record No: 0
Flight: AA123
Origin: BWI
Dest: SFO
No of passesngers: 235
Ticket Price: 239.5
Record No: 1
Flight: AA200
Origin: BOS
Dest: JFK
No of passesngers: 150
Ticket Price: 89.3
Writing to Text Files
• Several situations can exist:
• the file does not exist
• the file exists and we want to replace the current
contents
• the file exists and we want to append to the current
contents
• We specify whether we want to replace the
contents or append to the current contents.
22
Selected java.io Output Classes
Class
Description
Writer
Abstract superclass for output classes
OutputStreamWriter Class to write output data streams
OutputStream
Abstract superclass representing an output stream
of raw bytes
FileWriter
Class for writing to character files
BufferedWriter
More efficient writing to character files
PrintWriter
Prints basic data types, Strings, and objects
PrintStream
Supports printing various data types conveniently
FileOutputStream
Output stream for writing raw bytes of data to files
ObjectOutputStream Class to write objects to a file
23
Hierarchy for Output Classes
24
Constructors for Writing to Text
Files
Class
Constructor
FileWriter
FileWriter( String filename,
boolean mode )
constructs a FileWriter object from a String
representing the name of a file. If the file does
not exist, it is created. If mode is false, the
current contents of the file, if any, will be
replaced. If mode is true, writing will append
data to the end of the file. Throws an
IOException.
BufferedWriter BufferedWriter( Writer w )
constructs a BufferedWriter object from a
Writer object
25
Buffering
• Writing data to the disk is much slower than writing
data into main memory.
• When a class uses buffering, instead of writing one
character at a time to the file, it accumulates the
data in a temporary location in memory, called a
buffer.
• When the buffer is full or is flushed, the
accumulated data is written to the file in one
efficient operation.
26
Methods of the BufferedWriter Class
Return value Method name and argument list
void
write( String s )
writes a String to the current OutputStream
object. This method is inherited from the Writer
class. Throws an IOException.
void
newLine( )
writes a line separator. Throws an
IOException.
void
close( )
releases resources allocated to the
BufferedWriter object. Throws an IOException.
See Example 11.9 WriteTextFile.java
and Example 11.10 AppendTextFile.java
27
Using BufferedWriter to Write to
Files
try
{
FileWriter fw = new FileWriter
( "grades.txt", false );
BufferedWriter bw = new
BufferedWriter( fw );
String s="CS130: ";
bw.write( s, 0, s.length());
counter=counter+s.length();
s="95";
bw.write( s, 0, s.length());
counter=counter+s.length();
bw.newLine();
s="Letter grade: ";
bw.write( s, 0, s.length());
counter=counter+s.length();
s="A";
bw.write( s, 0, s.length());
counter=counter+s.length();
bw.newLine();
bw.flush();
bw.close( );
}
catch (IOException e)
{
System.out.println(
"Text errors" );
}
Writing Primitive Types to Text Files
• FileOutputStream, a subclass of the OutputStream
class, is designed to write a stream of bytes to a
file.
• The PrintWriter class is designed for converting
primitive data types to characters and writing them
to an output stream.
• print method, writes data without a newline
• println method, writes data then adds a newline
29
Writing to Structured Text Files
Class
Constructor
FileOutputStream FileOutputStream( String filename,
boolean mode )
constructs a FileOutputStream object from
a String representing the name of a file. If
the file does not exist, it is created. If mode
is false, the current contents of the file, if
any, will be replaced. If mode is true, writing
will append data to the end of the file.
Throws a FileNotFoundException.
PrintWriter
PrintWriter( OutputStream os )
constructs a PrintWriter object from an
OutputStream object
30
Useful PrintWriter Methods
Return value
Method name and argument list
void
print( dataType argument )
writes a String representation of the argument to an
output stream
void
println( dataType argument )
writes a String representation of the argument to an
output stream followed by a newline.
void
close( )
releases the resources associated with the
PrintWriter object
• The argument can be any primitive data type (except byte or short), a char array,
or an object.
See Example 11.9 WriteGradeFile.java
31
Writing Primitive Types to Text Files
public static void main( String [ ] args )
{
try
{
FileOutputStream fos = new
FileOutputStream
( "grades.txt", false );
// false means we will be writing to
grades.txt,
// rather than appending to it
PrintWriter pw = new PrintWriter( fos );
// write data to the file
pw.print( "CS130: " );
pw.println( 95 );
pw.print( "Letter grade: " );
pw.println( 'A' );
pw.print( "Current GPA: " );
pw.println( 3.68 );
pw.print( "Successful student as of Spring
semester: " );
pw.println( true );
// release the resources associated with
grades.txt
pw.close( );
}
catch ( FileNotFoundException fnfe )
{
System.out.println( "Unable to find
grades.txt" );
}
}
Writing Primitive Types to Text Files
pw.print( "Current GPA: " );
public static void main( String [ ] args )
pw.println( 3.68 );
{
pw.print( "Successful student as of Spring
try
• Use a FileOutputStream object
semester: " );
{
• 2nd parameter is “false” which
pw.println( true );
FileOutputStream fos = new
deletes the existing content of
// release the resources associated with
FileOutputStream
the file
grades.txt
( "grades.txt", false );
pw.close( );
// false means we will be writing to
}
grades.txt,
// rather than appending to it
catch ( FileNotFoundException fnfe )
PrintWriter pw = new PrintWriter( fos );
{
// write data to the file
System.out.println( "Unable to find
pw.print( "CS130: " );
grades.txt" );
pw.println( 95 );
}
pw.print( "Letter grade: " );
}
pw.println( 'A' );
Writing Primitive Types to Text Files
public static void main( String [ ] args )
{
try
{
FileOutputStream fos = new
FileOutputStream
( "grades.txt", false );
// false means we will be writing to
grades.txt,
// rather than appending to it
PrintWriter pw = new PrintWriter( fos );
// write data to the file
pw.print( "CS130: " );
pw.println( 95 );
pw.print( "Letter grade: " );
pw.println( 'A' );
pw.print( "Current GPA: " );
pw.println( 3.68 );
pw.print( "Successful student as of Spring
semester: " );
pw.println( true );
// release the resources associated with
grades.txt
• Use a PrintWriter object with a
pw.close( );
FileOutputStream object to
}
write into a text file
catch ( FileNotFoundException fnfe )
{
System.out.println( "Unable to find
grades.txt" );
}
}
Writing Primitive Types to Text Files
public static void main( String [ ] args )
{
try
{
FileOutputStream fos = new
FileOutputStream
( "grades.txt", false );
// false means we will be writing to
grades.txt,
// rather than appending to it
PrintWriter pw = new PrintWriter( fos );
// write data to the file
pw.print( "CS130: " );
pw.println( 95 );
pw.print( "Letter grade: " );
pw.println( 'A' );
pw.print( "Current GPA: " );
pw.println( 3.68 );
pw.print( "Successful student as of Spring
semester: " );
pw.println( true );
// release the resources associated with
grades.txt
• print(), println() method to
pw.close( );
write data
}
catch ( FileNotFoundException fnfe )
{
System.out.println( "Unable to find
grades.txt" );
}
}
Writing Primitive Types to Text Files
public static void main( String [ ] args )
{
try
{
FileOutputStream fos = new
FileOutputStream
( "grades.txt", false );
// false means we will be writing to
grades.txt,
// rather than appending to it
PrintWriter pw = new PrintWriter( fos );
// write data to the file
pw.print( "CS130: " );
• Close
pw.println(
95 );the PrintWriter object
pw.print( "Letter grade: " );
pw.println( 'A' );
pw.print( "Current GPA: " );
pw.println( 3.68 );
pw.print( "Successful student as of Spring
semester: " );
pw.println( true );
// release the resources associated with
grades.txt
pw.close( );
}
catch ( FileNotFoundException fnfe )
{
System.out.println( "Unable to find
grades.txt" );
}
}
Appending to Text Files
pw.print( "Current GPA: " );
public static void main( String [ ] args )
pw.println( 3.68 );
{
pw.print( "Successful student as of Spring
try
• 2nd parameter is “true” which
semester: " );
{
add the new data to the end of
pw.println( true );
FileOutputStream fos = new
the file
// release the resources associated with
FileOutputStream
grades.txt
( "grades.txt", true );
pw.close( );
// false means we will be writing to
}
grades.txt,
// rather than appending to it
catch ( FileNotFoundException fnfe )
PrintWriter pw = new PrintWriter( fos );
{
// write data to the file
System.out.println( "Unable to find
pw.print( "CS130: " );
grades.txt" );
pw.println( 95 );
}
pw.print( "Letter grade: " );
}
pw.println( 'A' );
BufferedWriter Vs PrintWriter
• BufferedWriter is more efficient
• Buffering helps to make the write process faster
• PrintWriter has a large number of methods to
handle different data types
• Tedious to write using BufferedWriter
• You can combine them.
Using PrintWriter + BufferedWriter
try
{
FileWriter fw = new FileWriter
( "grades.txt", false );
BufferedWriter bw = new BufferedWriter( fw
);
PrintWriter pw=new PrintWriter(bw);
pw.print( "CS130: " );
pw.println( 95 );
pw.print( "Letter grade: " );
pw.println( 'A' );
pw.print( "Current GPA: " );
pw.println( 3.68 );
pw.print( "Successful student as of Spring
semester: " );
pw.println( true );
bw.flush();
pw.close( );
}
catch (IOException e)
{
System.out.println( "Text errors" );
}
Opening and Closing Standard Streams
• Some streams are standard and the are available to any
java program.
• The standard input stream (System.in), the standard
output stream (System.out), and the standard error
stream (System.err) are open when the program begins.
They are intended to stay open and should not be
closed.
40
SOFTWARE ENGINEERING TIP
• Calling the close method is optional. When the
program finishes executing, all the resources of any
unclosed files are released.
• It is good practice to call the close method, however,
especially if you will be opening a number of files (or
opening the same file multiple times.)
• Do not close the standard input, output, or error
devices, however. They are intended to remain open.
41
Closing an output stream
• When closing a Buffered output stream in addition
to the close() method for the stream the method
flush() should also be invoked:
• Flushing the output stream forces any buffered
output bytes to be written out.
42