CS 116: Object-‐Oriented Programming II Jim Sasaki from material

Lecture 11: More I/O
CS 116: Object-­‐Oriented Programming II !
Jim Sasaki from material by George Koutsogiannakis
Copyright: 2015 -­‐ Illinois Institute of Technology George Koutsogiannakis & Jim Sasaki
Topics
• The java.io Package • Reading Text Files • Reading Structured Text Files Using StringTokenizer • Reading using Streams • Writing to Structured Text Files
2
4
File Types
• Java basically supports two types of files: • text files: data is stored as characters • binary files: data is stored as raw bytes • The type of a file is determined by the classes used to write to the file. • Types of Files can be: • Files written using Bytes Streams (1s and 0s). • Files written using Character Streams (char types). • Files written in terms of Strings (text). • 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).
3
4
File Types
• 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
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. 5
4
Streams
• File writing and reading is accomplished with streams. • There are input and output streams • Input means reading from a file to your program or the console • Need a file input stream • Output means writing from your program or console to a file • Need a file output stream • java.io package provides classes for I/O streams.
6
4
Some java.io Input Classes
Class
InputStream
Description
Abstract superclass representing a
stream of raw bytes
FileInputStream
Input stream to read raw bytes of data
from files
ObjectInputStream
Class to read/recover objects from a
file written using ObjectOutputStream
7
4
Hierarchy for Input Classes
8
4
Some 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
9
4
Hierarchy for Output Classes
10
4
Reading Text Files with Scanner
• In CS115 we used the File object and the Scanner object to read a text file import java.io.File; import java.io.IOException; import java.util.Scanner; public class ReadFile { public static void main(String[] args) { try { File myfile=new File("mytextfile.txt"); Scanner scan=new Scanner(myfile); while(scan.hasMoreTokens()) { String str=scan.next(); System.out.println(str); } catch (IOException ioe) { System.out.println(ioe.toString()); } } }
11
4
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
close( )
void
Releases resources associated with an open
input stream. Throws an IOException.
12
4
Closing an Output Stream
• With a buffered output stream, flush the buffer before closing it, to force any data in the buffer to be written out. • dataStream.flush();
13
4
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. 14
4
Calling the Close Method
• Calling the close method is optional. When the program finishes executing, close is called if necessary • Good practice to call the close method, anyway, especially if you will be opening a number of files (or opening the same file multiple times.) • Don’t close the standard streams — They’re intended to remain open. 15
4
Exceptions While Reading from a File
• We can catch FileNotFoundException — can be thrown by Scanner constructor if we try to open a non-­‐existent file • We don’t expect the exceptions below; we’ll catch them as subclasses of IOException and print the stack trace. • InputMismatchException if the input does not match the expected data type. (The next method does not throw this exception, so we don’t need to catch this exception). • NoSuchElementException – try to read past end of file. • IllegalStateException — tried to read after calling close • See Example 11.8 ReadTextFile.java
16
4
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. 17
4
Example
• An airline company could store data in a file where each line represents a flight segment containing the following fields (a.k.a.“headers”) • Flight number, Origin airport, Destination airport, Number of passengers, Average ticket price • Such a file could contain the following data: • AA123,BWI,SFO,235,239.5 • AA200,BOS,JFK,150,89.3 • Two records (rows of data), with delimiter comma
18
4
StringTokenizer Class
• Can use java.util.StringTokenizer to break up a record into its parts, given a delimiter. • The FlightRecord class defines instance variables for each flight data value. • The ReadFlights class reads data from flights.txt, instantiates FlightRecord objects, and adds them to an ArrayList. • See Examples 11.12 FlightRecord.java and Example 11.13 ReadFlights.java
19
4
Reading using Streams that aren’t the Scanner
• Suggestion: from now on import the entire java.io package (java.io.*;) • Text files: files created by using Strings based streams ( written using the class PrintWriter). • Use: class PrintReader to read it. • Character Files: files created using char types (written using FileWriter class). • Use: class FileReader to read it. • Bytes Files -­‐binary data. (written using class FileOutputStream) • Use: class FileInputStream to read it.
20
4
Reading using Streams that aren’t the Scanner
• Primitive Data Type Files: files that have recorded strictly primitive data types (written using various methods depending on the primitive data type of class DataOutputStream ) • Use: class DataInputStream methods to read file. • These classes offer different write methods for primitive data types i.e. • public final void writeDouble(double v) throws IOException • Files that have Objects recorded: files written using ObjectOutputStream class methods. • Use class ObjectInput methods to read objects from the file.
21
4
Example: Reading Text File try { FileInputStream file=new FileInputStream("MyFile.txt"); BufferedReader filereader = new BufferedReader(new InputStreamReader(file)); int count = 0; // Want count = # items in file int index = filereader.read(); while (index >= 0) { count++; index = filereader.read(); } System.out.println(count); file.close(); filereader.close(); } catch(IOException ioe) { System.out.println(ioe.toString(); }
22
4
Example Reading Text File • This example uses a buffer stream, which wraps the file stream. • Calling the read method of InputStreamReader class reads one character and returns an int. • On end of the file, the int is -­‐1. • Which is why our while loop stops on a negative index
23
4
Example: Reading a Text File • The example only counts the characters; it doesn’t read them in. Since count = the number of records; we can create an array of the correct length char[] charArray = new char[count]; • After reopening the file, we can re-­‐read its characters into charArray[0], …, charArray[count-­‐1]: int index = filereader.read(charArray, 0, count); • The read routine sets index to the number of characters read (should = count, for us). • In the general case, it can also return -­‐1 for end of file.
24
4