Java IO Correcto
Java IO Correcto
Chapter Objectives
To understand how I/O is handled in Java To distinguish between text I/O and binary I/O To read and write bytes using FileInputStream and FileOutputStream
To read and write primitive values and strings using the DataInputStream and DataOutputStream classes
To store and restore objects using ObjectOutputStream and ObjectInputStream, and to understand how objects are serialized and what kind of objects can be serialized
Patrick Healy
Overview
The java.io.* package provides a library of classes to read and write various types of data. In Java, all data I/O is handled in the form of streams Data streams can be byte streams or character streams The java.io package has classes that process byte streams of all types NOTE: In Java, a character is 2 BYTES ! Also NOTE: a Unicode character is 2 bytes ! The Reader and Writer classes process character streams. Streams can be layered, so that one type of streams can be converted to another type of streams by chaining. Chaining a character stream reader to a byte stream reader to read bytes on one end and produce characters at the other end .
Patrick Healy
Program
File
Output Stream
Patrick Healy
ITP 120 Java Programming I
4
The stream classes can be categorized into two types: byte streams and character streams.
Patrick Healy
ByteArrayOutputStream FileOutputStream OutputStream FilterOutputStream PipeOutputStream ObjectOutputStream BufferedOutputStream DataOutputStream PrintStream ObjectOutput OutputData
Patrick Healy
RandomAccessFile
StreamTokenizer
Patrick Healy
File
Data stored in a text file are represented in human-readable form. Data stored in a binary file are represented in binary form. You cannot read binary files. Binary files are designed to be read by programs. For example, the Java source programs are stored in text files and can be read by a text editor, but the Java classes are stored in binary files and are read by the JVM. The advantage of binary files is that they are more efficient to process than text files. Although it is not technically precise and correct, you can imagine that a text file consists of a sequence of characters and a binary file consists of a sequence of bits. For example, the decimal integer 199 is stored as the sequence of three characters: '1', '9', '9' in a text file and the same integer is stored as a byte-type value C7 in a binary file, because decimal 199 equals to hex C7.
Binary I/O
Text I/O requires encoding and decoding. The JVM converts a Unicode to a file specific encoding when writing a character and coverts a file specific encoding to a Unicode when reading a character. Binary I/O does not require conversions. When you write a byte to a file, the original byte is copied into the file. When you read a byte from a file, the exact byte in the file is returned.
Text I/O program (a) The Unicode of the character e.g. "199" , Encoding/ Decoding
The encoding of the character is stored in the file 00110001 00111001 00111001 0x31 0x39 0x39
InputStream
java.io.InputStream +read(): int
The value returned is a byte as an int type. Reads the next byte of data from the input stream. The value byte is returned as
an int value in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value 1 is returned. Reads up to b.length bytes into array b from the input stream and returns the actual number of bytes read. Returns -1 at the end of the stream. Reads bytes from the input stream and stores into b[off], b[off+1], , b[off+len-1]. The actual number of bytes read is returned. Returns -1 at the end of the stream. Returns the number of bytes that can be read from the input stream. Closes this input stream and releases any system resources associated with the stream. Skips over and discards n bytes of data from this input stream. The actual number of bytes skipped is returned.
+read(b: byte[]): int +read(b: byte[], off: int, len: int): int +available(): int +close(): void +skip(n: long): long
+markSupported(): boolean Tests if this input stream supports the mark and reset methods. +mark(readlimit: int): void Marks the current position in this input stream. +reset(): void Repositions this stream to the position at the time the mark method was last called on this input stream.
OutputStream
The value is a byte as an int type.
java.io.OutputStream +write(int b): void +write(b: byte[]): void Writes the specified byte to this output stream. The parameter b is an int value. (byte)b is written to the output stream. Writes all the bytes in array b to the output stream.
+write(b: byte[], off: int, Writes b[off], b[off+1], , b[off+len-1] into the output stream. len: int): void +close(): void +flush(): void Closes this input stream and releases any system resources associated with the stream. Flushes this output stream and forces any buffered output bytes to be written out.
FileInputStream/FileOutputStream
FileInputStream DataInputStream InputStream FilterInputStream BufferedInputStream ObjectInputStream Object FileOutputStream OutputStream FilterOutputStream ObjectOutputStream BufferedOutputStream DataOutputStream PrintStream
FileInputStream/FileOutputStream associates a binary input/output stream with an external file. All the methods in FileInputStream/FileOuptputStrea
FileInputStream
To construct a FileInputStream, use the following constructors: public FileInputStream(String filename) public FileInputStream(File file) A java.io.FileNotFoundException would occur if you attempt to create a FileInputStream with a nonexistent file.
FileOutputStream
To construct a FileOutputStream, use the following constructors:
public FileOutputStream(String filename) public FileOutputStream(File file) public FileOutputStream(String filename, boolean append) public FileOutputStream(File file, boolean append)
TestFileStream
Run
If the file does not exist, a new file would be created. If the file already exists, the first two constructors would delete the current contents in the file. To retain the current content and append new data into the file, use the last two constructors by passing true to the append parameter.
FilterInputStream/FilterOutputStream
FileInputStream DataInputStream InputStream FilterInputStream BufferedInputStream ObjectInputStream Object FileOutputStream OutputStream FilterOutputStream ObjectOutputStream BufferedOutputStream DataOutputStream PrintStream
Filter streams are streams that filter bytes for some purpose. The basic byte input stream provides a read method that can only be used for reading bytes. If you want to read integers, doubles, or strings, you need a filter class to wrap the byte input stream. Using a filter class enables you to read integers, doubles, and strings instead of bytes and characters. FilterInputStream and FilterOutputStream are the base classes for filtering data. When you need to process primitive numeric types, use DatInputStream and DataOutputStream to filter bytes.
DataInputStream/DataOutputStream
DataInputStream reads bytes from the stream and converts them into appropriate primitive type values or strings.
FileInputStream DataInputStream InputStream FilterInputStream BufferedInputStream ObjectInputStream Object FileOutputStream OutputStream FilterOutputStream ObjectOutputStream BufferedOutputStream DataOutputStream PrintStream
DataOutputStream converts primitive type values or strings into bytes and output the bytes to the stream.
DataInputStream
DataInputStream extends FilterInputStream and implements the DataInput interface.
InputStream java.io.DataInput +readBoolean(): boolean Reads a Boolean from the input stream. +readByte(): byte Reads a byte from the input stream. +readChar(): char +readFloat(): float +readDouble(): float DataInputStream +DataInputStream( in: InputStream) +readInt(): int +readLong(): long +readShort(): short +readLine(): String +readUTF(): String Reads a character from the input stream. Reads a float from the input stream. Reads a double from the input stream. Reads an int from the input stream. Reads a long from the input stream. Reads a short from the input stream. Reads a line of characters from input. Reads a string in UTF format.
FilterInputStream
DataOutputStream
DataOutputStream extends FilterOutputStream and implements the DataOutput interface.
OutputStream java.io.DataOutput +writeBoolean(b: Boolean): void Writes a Boolean to the output stream. +writeByte(v: int): void Writes to the output stream the eight low-order bits of the argument v. +writeBytes(s: String): void Writes the lower byte of the characters in a string to the output stream. +writeChar(c: char): void Writes a character (composed of two bytes) to the output stream. +writeChars(s: String): void Writes every character in the string s, to the output stream, in order, two bytes per character. +writeFloat(v: float): void Writes a float value to the output stream. +writeDouble(v: float): void +writeInt(v: int): void +writeLong(v: long): void +writeShort(v: short): void +writeUTF(s: String): void Writes a double value to the output stream. Writes an int value to the output stream. Writes a long value to the output stream. Writes a short value to the output stream. Writes two bytes of length information to the output stream, followed by the UTF representation of every character in the string s.
FilterOutputStream
UTF-8 is a coding scheme that allows systems to operate with both ASCII and Unicode efficiently. Most operating systems use ASCII. Java uses Unicode. The ASCII character set is a subset of the Unicode character set. Since most applications need only the ASCII character set, it is a waste to represent an 8-bit ASCII character as a 16-bit Unicode character. The UTF8 is an alternative scheme that stores a character using 1, 2, or 3 bytes. ASCII values (less than 0x7F) are coded in one byte. Unicode values less than 0x7FF are coded in two bytes. Other Unicode values are coded in three bytes.
Using DataInputStream/DataOutputStream
Data streams are used as wrappers on existing input and output streams to filter data in the original stream. They are created using the following constructors:
public DataInputStream(InputStream instream) public DataOutputStream(OutputStream outstream)
The statements given below create data streams. The first statement creates an input stream for file in.dat; the second statement creates an output stream for file out.dat.
DataInputStream infile = new DataInputStream(new FileInputStream("in.dat")); TestDataStream DataOutputStream outfile = new DataOutputStream(new FileOutputStream("out.dat"));
Run
BufferedInputStream/ BufferedOutputStream
FileInputStream InputStream FilterInputStream
DataInputStream BufferedInputStream ObjectInputStream Object FileOutputStream OutputStream FilterOutputStream ObjectOutputStream BufferedOutputStream DataOutputStream PrintStream
BufferedInputStream/BufferedOutputStream does not contain new methods. All the methods BufferedInputStream/BufferedOutputStream are inherited from the InputStream/OutputStream classes.
Constructing BufferedInputStream/BufferedOutputStream
// Create a BufferedInputStream public BufferedInputStream(InputStream in) public BufferedInputStream(InputStream in, int bufferSize)
// Create a BufferedOutputStream public BufferedOutputStream(OutputStream out) public BufferedOutputStream(OutputStreamr out, int bufferSize)
The program copies a source file to a target file and displays the number of bytes in the file. If the source does not exist, tell the user the file is not found. If the target file already exists, tell the user the file already exists. Copy Run
Optional
Object I/O
DataInputStream/DataOutputStream enables you to perform I/O for primitive type values and strings. ObjectInputStream/ObjectOutputStream enables you to perform I/O for objects in addition for primitive type values and strings.
FileInputStream DataInputStream InputStream FilterInputStream BufferedInputStream ObjectInputStream
ObjectInputStream
ObjectInputStream extends InputStream and implements ObjectInput and ObjectStreamConstants.
java.io.InputStream
ObjectOutputStream
ObjectOutputStream extends OutputStream and implements ObjectOutput and ObjectStreamConstants.
java.io.OutputStream
Run
Run
RandomAccessFile
DataInput java.io.RandomAccessFile +RandomAccessFile(file: File, mode: String) +RandomAccessFile(name: String, mode: String) +close(): void +getFilePointer(): long +length(): long +read(): int +read(b: byte[]): int +read(b: byte[], off: int, len: int) : int +seek(long pos): void +setLength(newLength: long): void +skipBytes(int n): int +write(b: byte[]): void +write(byte b[], int off, int len) +write(b: byte[], off: int, len: int): void Creates a RandomAccessFile stream with the specified File object and mode. Creates a RandomAccessFile stream with the specified file name string and mode. Closes the stream and releases the resource associated with the stream. Returns the offset, in bytes, from the beginning of the file to where the next read or write occurs. Returns the length of this file. Reads a byte of data from this file and returns 1 an the end of stream. Reads up to b.length bytes of data from this file into an array of bytes. Reads up to len bytes of data from this file into an array of bytes. Sets the offset (in bytes specified in pos) from the beginning of the stream to where the next read or write occurs. Sets a new length of this file. Skips over n bytes of input discarding the skipped bytes. Writes b.length bytes from the specified byte array to this file, starting at the current file pointer. Writes len bytes from the specified byte array starting at offset off to this file. DataInput
File Pointer
A random access file consists of a sequence of bytes. There is a special marker called file pointer that is positioned at one of these bytes. A read or write operation takes place at the location of the file pointer. When a file is opened, the file pointer sets at the beginning of the file. When you read or write data to the file, the file file pointer moves forward to the next data. For pointer example, if you read an int value using readInt(), the file byte byte byte byte byte byte byte byte byte byte byte byte (A) Before readInt() JVM reads four bytes from the file pointer and now the file pointer file pointer is four bytes ahead of the previous location.
file byte byte byte byte byte byte byte byte byte byte byte byte (B) Before readInt()
RandomAccessFile Methods
Many methods in RandomAccessFile are the same as those in DataInputStream and DataOutputStream. For example, readInt(), readLong(), writeDouble(), readLine(), writeInt(), and writeLong() can be used in data input stream or data output stream as well as in RandomAccessFile streams.
long
getFilePointer() IOException;
Returns the current offset, in bytes, from the beginning of the file to where the next read or write occurs.
length()IOException
final
RandomAccessFile Constructor
RandomAccessFile raf = new RandomAccessFile("test.dat", "rw"); //allows read and write RandomAccessFile raf = new RandomAccessFile("test.dat", "r"); //read only
Optional
Now let us use RandomAccessFile to create a useful project for storing and viewing and address book. The user interface of the program is shown in Figure 16.24. The Add button stores a new address to the end of the file. The First, Next, Previous, and Last buttons retrieve the first, next, previous, and last addresses from the file, respectively.
FixedLengthStringIO
CopyFile.java is a program that copies files. The user needs to provide a source file and a target file as command-line arguments using the following command:
The program copies a source file to a target file and displays the number of bytes in the file. If the source does not exist, tell the user the file is not found. If the target file already exists, tell the user the file already exists.
Patrick Healy
41
FileInputStream DataInputStream InputStream FilterInputStream BufferedInputStream ObjectInputStream Object FileOutputStream OutputStream FilterOutputStream ObjectOutputStream BufferedOutputStream DataOutputStream PrintStream
Patrick Healy
42
ObjectInputStream (optional)
ObjectInputStream extends InputStream and implements ObjectInput and ObjectStreamConstants.
java.io.InputStream
Patrick Healy
43
ObjectOutputStream (optional)
ObjectOutputStream extends OutputStream and implements ObjectOutput and ObjectStreamConstants.
java.io.OutputStream
Patrick Healy
44
Patrick Healy
45
Patrick Healy
46
Patrick Healy
47
public class ITP120 implements java.io.Serializable { private int v1; private static double v2; private transient A v3 = new A(); } class A { } // A is not serializable
When an object of the ITP120 class is serialized, only variable v1 is serialized. Variable v2 is not serialized because it is a static variable, and variable v3 is not serialized because it is marked transient. If v3 were not marked transient, a java.io.NotSerializableException would occur.
Patrick Healy
48
Patrick Healy
49
Patrick Healy
50
RandomAccessFile
Creates a RandomAccessFile stream with the specified File object and mode. Creates a RandomAccessFile stream with the specified file name string and mode. Closes the stream and releases the resource associated with the stream. Returns the offset, in bytes, from the beginning of the file to where the next read or write occurs. Returns the length of this file. Reads a byte of data from this file and returns 1 an the end of stream. Reads up to b.length bytes of data from this file into an array of bytes. Reads up to len bytes of data from this file into an array of bytes. Sets the offset (in bytes specified in pos) from the beginning of the stream to where the next read or write occurs. Sets a new length of this file. Skips over n bytes of input discarding the skipped bytes. Writes b.length bytes from the specified byte array to this file, starting at the current file pointer. Writes len bytes from the specified byte array starting at offset off to this file.
Patrick Healy
51
File Pointers
A random access file consists of a sequence of bytes. There is a special marker called file pointer that is positioned at one of these bytes. A read or write operation takes place at the location of the file pointer. When a file is opened, the file pointer sets at the beginning of the file. When you read or write data to the file, the file pointer moves forward to the next data. For example, if you read an int value using readInt(), the JVM reads four bytes from the file pointer and now the file pointer is four bytes ahead of the previous location.
Patrick Healy
52
file
byte byte
file
byte byte
Patrick Healy
53
Methods
Many methods in RandomAccessFile are the same as those in DataInputStream and DataOutputStream. For example, readInt(), readLong(), writeDouble(), readLine(), writeInt(), and writeLong() can be used in data input stream or data output stream as well as in RandomAccessFile streams.
Patrick Healy
54
Patrick Healy
55
long length()IOException
Returns the length of the file.
Patrick Healy
56
Patrick Healy
57
59
HasNextLineDemo.java
BufferReaderDemo.java
60
62
Patrick Healy
63
Chapter 18: More on Input and Output Stream Classes (byte & character streams)
Predefined
Streams Print Streams Buffered Streams Text Input and Output on the Console Random Access Files
Patrick Healy
64
Understand input & output streams and learn how to create them.
Discover the uses of byte and character streams. To know how to read from / write to external files using file streams. To become familiar with the File class. To use print streams to output data of primitive types in text format. To know how to read and write text data files. Use text input and output on the console. Use RandomAccessFile for reading & writing random access files.
Patrick Healy
65
Overview
The java.io.* package provides a library of classes to read and write various types of data. In Java, all data I/O is handled in the form of streams Data streams can be byte streams or character streams The java.io package has classes that process byte streams of all types NOTE: In Java, a character is 2 BYTES ! NOTE: Unicode character is 2 bytes ! The Reader and Writer classes process character streams. Streams can be layered, so that one type of streams can be converted to another type of streams by chaining. Chaining a character stream reader to a byte stream reader to read bytes on one end and produce characters at the other end .
Patrick Healy
66
Overview Streams
Patrick Healy
67
Program
File
Output Stream
Patrick Healy
ITP 120 Java Programming I
68
The original version of Java defined only the byte stream, but character streams were quickly added.
Byte streams can be used when reading or writing binary data. Character streams are designed for handling character I/O. Character streams use UNICODE. In Java, a character is 2 bytes Unicode is for the internationalization of Java in different languages. The Java I/O system is quite LARGE because of the TWO separate class hierarchies of bytes and streams.
Patrick Healy
69
File
Data stored in a text file are represented in human-readable form. Data stored in a binary file are represented in binary form. You cannot read binary files. Binary files are designed to be read by programs. For example, the Java source programs are stored in text files and can be read by a text editor, but the Java classes are stored in binary files and are read by the JVM. The advantage of binary files is that they are more efficient to process than text files.
Although it is not technically precise and correct, you can imagine that a text file consists of a sequence of characters and a binary file consists of a sequence of bits. For example, the decimal integer 199 is stored as the sequence of three characters: '1', '9', '9' in a text file and the same integer is stored as a byte-type value C7 in a binary file, because decimal 199 equals to hex C7 ( 12 x 16 + 7 = 192 + 7 = 199 decimal )
Patrick Healy
ITP 120 Java Programming I
71
Binary I/O
Text I/O requires encoding and decoding. The JVM converts a Unicode character to file-specific encoding when writing a character, and coverts a file-specific encoding to a Unicode character when reading a character. Binary I/O does not require conversions. When you write a byte to a file, the original byte is copied into the file. When you read a byte from a file, the exact byte in the file is returned.
Text I/O program (a) The Unicode of the character e.g. "199" , Encoding/ Decoding
The encoding of the character is stored in the file 00110001 00111001 00111001 0x31 0x39 0x39
The stream classes can be categorized into two types: byte streams and character streams.
Patrick Healy
73
ByteArrayOutputStream FileOutputStream OutputStream FilterOutputStream PipeOutputStream ObjectOutputStream BufferedOutputStream DataOutputStream PrintStream ObjectOutput OutputData
Patrick Healy
RandomAccessFile
74
StreamTokenizer
Patrick Healy
75
These variables are declared as public and static with the System class. This means they can be used by any other part of your program and without a reference to a specific object in the System class.
Patrick Healy
76
System class
System.in refers to the standard input stream which is the keyboard by default. (Keyboard )
System.out refers to the standard output stream which is the console by default. (Monitor) System.err refers to the standard error stream which is also the console by default. (Monitor) These streams may be redirected to any compatible I/O device.
Patrick Healy
77
Patrick Healy
78
// Read an array of bytes from the keyboard. import java.io.*; public class ReadBytes { public static void main(String[ ] args) throws IOException { byte data[ ] = new byte[10]; // Byte array data holds 10 bytes
System.out.println("Enter some characters:"); System.in.read(data); // Use the read method to read some bytes System.out.print("You entered: "); for(int i=0; i < data.length; i++) System.out.print((char) data[i]); // Cast data to a character } // End main method } // End class ReadBytes
Patrick Healy
ITP 120 Java Programming I
79
Patrick Healy
80
Patrick Healy
81
The java.io package provides two categories of classes: Byte stream readers and writers Character stream readers and writers At the top of the hierarchy for stream classes are the abstract classes InputStream and Output Stream The subclasses branch out and specializes into the different types of streams that they handle. InputData, OutputData, and ObjectInput interfaces are implemented by the classes that handle data, such as, int, double, char, etc., and objects. Only ObjectInput specifies methods for reading objects. DataInputStream - which is a subclass of FilterInputStream, which in turn is a subclass of InputStream implements the InputData interface and can read primitive data, and objects from byte streams.
Patrick Healy
82
Stream Classes
Patrick Healy
83
The following methods are defined in InputStream and are often useful:
public abstract int read() throws IOException Reads the next byte and returns its value in the range of 0 to 255. At the end of the stream, it returns a - 1.
Patrick Healy
84
The following methods are defined in InputStream and are often useful:
Patrick Healy
85
The following method is defined in InputStream and is often useful: public long skip(long n) throws IOException Skip over and discard n bytes of data from the input stream. The actual number of bytes skipped is returned.
Patrick Healy
86
Once the file is open, you can read from the file or write to the file.
To read form a file, you may use the read( ) method. int read( ) throws IOException
When you are done with a file, you should close it by calling close()
void close( ) throws IOException Closing a file releases the system resources allocated to the file, allowing them to be used by another file.
Patrick Healy
87
Patrick Healy
88
Patrick Healy
89
Patrick Healy
90
Patrick Healy
91
Patrick Healy
92
// try to open input file try { // inner try fin = new FileInputStream(args[0]); } catch(FileNotFoundException exc) { System.out.println(Error: + exc.getMessage( ) );
Patrick Healy
94
95
So far, we have been reading and writing bytes containing ASCII bytes.
You may want to create a file that contains other types of data such as integers, doubles, or shorts , that is: int, double, short, etc. In Java, to read and write binary values of the simple Java data types, you should use: DataInputStream and DataOutputStream (for binary data)
DataOutputStream implements the OutputData interface. The OutputData interface defines methods that write all of Javas simple data types to a file.
Patrick Healy
96
The constructor for DataOutputStream is: DataOutputStream(OutputStream outputStream) outputStream is the stream to which the binary data is written.
Patrick Healy
97
DataInputStream implements the DataInput interface which provides the methods for reading all of Javas simple data types. DataInputStream uses an InputStream instance as its foundation, overlaying it with methods that read the various Java data types.
Patrick Healy
98
Patrick Healy
99
boolean readBoolean ( ) byte readByte ( ) char readChar ( ) double readDouble( ) float readFloat ( ) int readInt ( ) long readLong ( ) short readShort ( )
Patrick Healy
100
void writeBoolean (boolean val) void writeByte (int val) void writeChar(int val) void writeDouble(double val) void writeFloat(float val) void writeInt(int val) void writeLong(long val) void writeShort(int val)
Patrick Healy
101
Here is a Java program that demonstrates DataOutputStream and DataInputStream. It writes and then reads back various types of data to and from a file.
import java.io.*;
public class RWData { public static void main(String[ ] args) throws IOException
{
DataOutputStream dataOut; // Declare output, input file pointers DataInputStream dataIn;
Patrick Healy
102
Patrick Healy
103
d = dataIn.readDouble();
System.out.println("Reading " + d); b = dataIn.readBoolean(); System.out.println("Reading " + b); d = dataIn.readDouble(); System.out.println("Reading " + d); }
Patrick Healy
ITP 120 Java Programming I
106
Patrick Healy
107
Class #15 Input and Output Reader class methods for reading characters The Reader class is similar to the InputStream class. The methods in Reader are subject to character interpretation.
IOException
public void close() throws IOException public void skip() throws IOException
Patrick Healy
108
Like InputStream (for reading bytes) and Reader (for reading characters), OutputStream and Writer are the counterparts. They are the base classes for for all output streams of bytes and characters, respectively.
The next slide shows methods which are in both OutputStream and Writer. See next slide ->
Patrick Healy
109
(Writing bytes)
public abstract void write(int b) throws IOException Write a byte b (for OutputStream) or a charcter (for Writer) public void write(byte[] b) throws IOException This method writes all bytes in the array b to the output stream (for OutputStream) or characters in the array of characters (for Writer)
public void close() throws IOException This method closes the output stream. public void flush() throws IOException Flush the output stream and send any buffered data in the stream to its destination.
Patrick Healy
110
public abstract void write(int b) throws IOException Write a byte b (for OutputStream) or a character (for Writer) public void write(byte[] b) throws IOException This method writes all bytes in the array b to the output stream (for OutputStream) or characters in the array of characters (for Writer)
public void close() throws IOException This method closes the output stream. public void flush() throws IOException Flush the output stream and send any buffered data in the stream to its destination.
Patrick Healy
111
Patrick Healy
112
Patrick Healy
113
Patrick Healy
114
stream that is linked to the console thru System.in (which reads bytes)
Patrick Healy
115
Reading Characters
Characters can be read from System.in using the read( ) method defined by BufferedReader.
int read( ) throws IOException int read(char data[ ] ) throws IOException int read(char data[ ], int start, int max) throws IOException
Patrick Healy
116
int read( ) throws IOException reads a single Unicode character and returns a -1 when the end of the stream is reached. int read(char data[ ]) throws IOException reads characters from the input stream until: (1) the array is full, (2) EOF is reached, or (3) an error occurs. int read(char data[ ], int start, int max) throws IOException reads input into array data beginning at the location specified by start, storing up to max characters. It returns the number of characters read or -1 when the end of the stream is reached. Pressing the [Enter] key generates an end-of-stream condition.
Patrick Healy
117
The following program demonstrates the read( ) method by reading characters from the console until the user types a period.
// Use a BufferedReader to read characters from the console. import java.io.*; public class ReadChars { public static void main(String[ ] args) throws IOException {
Patrick Healy
118
Patrick Healy
119
J A V A .
<- note the period character which stopped the input stream
Patrick Healy
120
String readLine( ) throws IOException It returns a string object that contains the characters read. It returns null if an attempt is made to read beyond the end of the stream.
Patrick Healy
121
The following program demonstrates BufferedReader and the readLine() method. The program reads and displays lines of text until the user enters the word stop
import java.io.*;
// Read a string from console using a BufferedReader. class ReadLines { public static void main(String[ ] args) throws IOException {
Patrick Healy
122
Patrick Healy
123
The preferred method of writing to the console (monitor) when using Java is through a PrintWriter stream.
PrintWriter is one of the character-based classes. Using a character-based class makes it easier to internationalize Java programs. PrintWriter has several constructors, but this is the one to be used in the demonstration program which is on the following slides:
Patrick Healy
124
Patrick Healy
125
Patrick Healy
126
Patrick Healy
127
Patrick Healy
128
Patrick Healy
Patrick Healy
130
Patrick Healy
131
Patrick Healy
132
Patrick Healy
133
Patrick Healy
134
Patrick Healy
135
To discover file properties, delete and rename files using the File class To understand how I/O is processed in Java To distinguish between text I/O and binary I/O To read and write characters using FileReader and FileWriter To improve the performance of text I/O using BufferedReader and BufferedWriter To write primitive values, strings, and objects as text using PrintWriter and PrintStream To read and write bytes using FileInputStream and FileOutputStream To read and write primitive values and strings using DataInputStream/DataOutputStream To store and restore objects using ObjectOutputStream and ObjectInputStream, and to understand how objects are serialized and what kind of objects can be serialized To use RandomAccessFile for both read and write.
Patrick Healy
136
The File class is intended to provide an abstraction that deals with most of the machine-dependent complexities of files and path names in a machine-independent fashion. The filename is a string. The File class is a wrapper class for the file name and its directory path.
Patrick Healy
137
+File(pathname: String)
Creates a File object for the specified pathname. The pathname may be a directory or a file.
+File(parent: String, child: String) Creates a File object for the child under the directory parent. child may be a filename or a subdirectory. +File(parent: File, child: String) Creates a File object for the child under the directory parent. parent is a File object. In the preceding constructor, the parent is a string. +exists(): boolean Returns true if the file or the directory represented by the File object exists. +canRead(): boolean +canWrite(): boolean +isDirectory(): boolean +isFile(): boolean +isAbsolute(): boolean +isHidden(): boolean Returns true if the file represented by the File object exists and can be read. Returns true if the file represented by the File object exists and can be written. Returns true if the File object represents a directory. Returns true if the File object represents a file. Returns true if the File object is created using an absolute path name. Returns true if the file represented in the File object is hidden. The exact definition of hidden is system-dependent. On Windows, you can mark a file hidden in the File Properties dialog box. On Unix systems, a file is hidden if its name begins with a period character '.'. Returns the complete absolute file or directory name represented by the File object. Returns the same as getAbsolutePath() except that it removes redundant names, such as "." and "..", from the pathname, resolves symbolic links (on Unix platforms), and converts drive letters to standard uppercase (on Win32 platforms). Returns the last name of the complete directory and file name represented by the File object. For example, new File("c:\\book\\test.dat").getName() returns test.dat. Returns the complete directory and file name represented by the File object. For example, new File("c:\\book\\test.dat").getPath() returns c:\book\test.dat. Returns the complete parent directory of the current directory or the file represented by the File object. For example, new File("c:\\book\\test.dat").getParent() returns c:\book. Returns the time that the file was last modified. Deletes this file. The method returns true if the deletion succeeds.
+getName(): String
Patrick Healy
ITP 120Renames this file. The method returns true if the operation succeeds. Java Programming I
138
TestFileClass.java
Objective: Write a program that demonstrates how to create files in a platform-independent way and use the methods in the File class to obtain their properties. Figure 1 shows a sample run of the program on Windows, and Figure 2 a sample run on Unix (Windows) (Unix)
Patrick Healy
139
The File class provides an abstraction that deals with most of the machine-dependent complexities of files and path names in a machineindependent fashion. You can create a new File object using the following statement:
File myfile = new File (myfile.dat);
You can use the File class to check properties of files, such as whether the file exists, or is readable, or updateable.
Patrick Healy
140
You can use the getName( ) method to get the name of the file.
For example, if (myfile.exists( ) ) System.out.println(File + myfile.getName( ) + already exists);
The following statement creates a file using the full path using the Windows operating system: File myfile = new File(C:\\Java\\myfile.data);
Patrick Healy
141
You can use the getPath( ) method to get the full path of the file and the getParent( ) method to get the directory that contains the file.
For example, if (myfile.exists( ) ) { System.out.println(The full path is + myfile.getPath( ) ); System.out.println(The directory is + myfile.getParent( ) ); }
Patrick Healy
142
Patrick Healy
}
}
144
Patrick Healy
Patrick Healy
145
Patrick Healy
146
FileInputStream infile = new FileInputStream("in.dat"); FileOutputStream outfile = new FileOutputStream("out.dat"); FileReader infile = new FileReader("in.dat"); FileWriter outfile = new FileWriter("out.dat");
Patrick Healy
147
Patrick Healy
149
public class TestFileWriter { public static void main(String[ ] args) throws IOException { // Create an output stream to the file FileWriter output = new FileWriter("temp.txt", true); // Output a string to the file output.write( NVCC Introduction to Java Programming ITP 120 !!!"); // Close the stream output.close(); } }
Patrick Healy
150
args[0] args[1]
Patrick Healy
151
Patrick Healy
152
public class CopyFileUsingByteStream { // Main method: args[0] for sourcefile and args[1] for target file public static void main(String[ ] args) { // Declare input and output file streams FileInputStream fis = null; FileOutputStream fos = null;
Patrick Healy
153
Patrick Healy
154
fis = new FileInputStream(new File(args[0])); // Create file output stream if the file does not exist File outFile = new File(args[1]); if (outFile.exists()) { System.out.println("file " + args[1] + " already exists"); return; }
Patrick Healy
155
fos = new FileOutputStream(args[1]); // FileOutputStream // Display the file size System.out.println("The file " + args[0] + " has "+ fis.available() + " bytes");
Patrick Healy
156
catch (FileNotFoundException ex) { System.out.println(Error: + ex.getMessage( ) ); System.out.println("File not found: " + args[0]); }
Patrick Healy
157
Patrick Healy
158
finally { try { if (fis != null) fis.close(); // Close the input & output files if (fos != null) fos.close(); } catch (IOException ex) { System.out.println(Error: + ex.getMessage( ) ); } } // End of finally block } // End of main method } // End of class CopyFileUsingByteStream
Patrick Healy
ITP 120 Java Programming I
159
Filter Streams
Filter streams are streams that filter bytes or characters for some purpose.
If you want to read integers, doubles, or Strings, you need a filter class to wrap the input stream. Using a filter class enables you to read integers, doubles, and strings instead of bytes and characters. Use FilterInputStream and FilterOutputStream when you need to process primitive numeric types.
Patrick Healy
160
Filter Streams
Patrick Healy
161
FilterInputStream subclasses
Patrick Healy
162
FilterOutputStream subclasses
DataOutputStream outputs the binary formats for all primitive data types which is useful if another program uses the output. BufferedOutputStream outputs to the buffer first and then to the stream if necessary. You may also call the flush( ) method to write the buffer to the stream. PrintStream outputs the Unicode format of all primitive types which is useful if the format is output to the console.
Patrick Healy
163
Data Streams
(bytes)
The data streams (DataInputStream and DataOutputStream) read and write Java primitive types in a machine-independent fashion. This enables you to write a data file for one computer and read it on another computer that has a different operating system or file structure.
Patrick Healy
164
int readByte() throws IOException int readShort() throws IOException int readInt() throws IOException int readLong() throws IOException
Patrick Healy
Patrick Healy
166
Data streams are used as wrappers on existing input and output streams to filter data in the original stream.
DataInputStream infile = new DataInputStream(new FileInputStream("in.dat"));
Patrick Healy
168
Demo Example
Patrick Healy
169
Demo Example
File tempFile = new File("mytemp.dat"); // Check if the temp file exists if (tempFile.exists()) { System.out.println("The file mytemp.dat already exists," +" delete it, rerun the program"); System.exit(0); }
Patrick Healy
170
Demo Example
// Create data output stream for tempFile dos = new DataOutputStream(new FileOutputStream(tempFile)); for (int i=0; i<10; i++) dos.writeInt((int)(Math.random()*1000)); }
Patrick Healy
171
Demo Example
System.out.println(ex.getMessage( ) ); }
finally
{ try { if (dos != null) dos.close( ); } catch (IOException ex) { System.out.println(Error: + ex.getMessage( ) ); } // Close the file(s)
Patrick Healy
172
Demo Example
// Create data input stream dis = new DataInputStream(new FileInputStream(tempFile)); for (int i=0; i<10; i++) System.out.print(" "+dis.readInt ( ) ); // Display the integers }
Patrick Healy
173
Patrick Healy
174
if (dis != null)
}
catch (IOException ex) { System.out.println(Error: + ex.getMessage( ) )); } } // End of finally block } // End of main method } // End of class TestDataStreams
Patrick Healy
ITP 120 Java Programming I
175
Demo Example
The previous Java program TestDataStreams.java creates a DataInputStream object named dis wrapped on FileInputStream and creates a DataOutputStream object dos wrapped on FileOutputStream Conceptually,
Program DataInputStream dis <-- fileInputStream <--mytemp.dat DataOutputStream dos fileOutputStream mytemp.dat The program uses a temporary file, mytemp.dat, to store data. The program creates mytemp.dat if it does not exist and writes 10 random
Patrick Healy
176
Character Classes
The classes that handle characters have at the top of their hierarchy, Reader and Writer
The subclasses branch out to provide specialized functionality. FileReader provides functionality for reading streams of characters from files. BufferedReader buffers character streams for efficiency FileWriter for writing character streams to files.
Patrick Healy
File Class
Patrick Healy
178
File Class
Patrick Healy
Reading data from the keyboard BufferedReader in = new BufferedReader(new InputStreamReader(System.in); An InputStreamReader is like an adapter, it reads byte streams and converts it into character streams BufferedReader wraps the InputStreamReader to provide extra functionality, allowing to buffer the input to support readLine()
Patrick Healy
180
Example Reading strings from the keyboard Import java.io.* public class ReadStringFromKeyboard { public static void main(String[ ] args) { // Converts from bytes to characters BufferedReader in = new BufferedReader(new InputStreamReader (System.in)); String yourInput; try { System.out.println("Please enter any string and hit the return key when done:"); yourInput = in.readLine( ); System.out.println("\nBelow is the input you entered"); System.out.println(yourInput); } catch (IOException ex) { System.out.println(Could not read from the keyboard } } // End of main method } // End of class ReadStringFromKeyboard Programming I ITP 120 Java Patrick Healy
181
public class ReadFromFile { public static void main(String[ ] args) { String st = null; File inputFileName = null; FileReader inputFile = null; BufferedReader in = null; try { inputFileName = new File("Input1.txt"); inputFile = new FileReader(inputFileName); in = new BufferedReader(inputFile); /* Note: The above 3 lines can be combined in one line as below in = new BufferedReader(new FileReader(new File("Input1.txt")));
*/
Patrick Healy
182
Patrick Healy
183
Example continued
finally { if( br != null) try { br.close( ); // Close the file } catch (Exception ex) { System.out.println(Error: + ex.getMessage( ) ); System.out.println("There was a problem with closing the file"); } } // End finally block } // End of main method } // End of class
Patrick Healy
ITP 120 Java Programming I
184
Print Streams
The data output stream outputs a binary representation of data, so you cannot view its contents as text. In Java, you can use print streams to output data into files. These files can then be viewed as text. The PrintStream and PrintWriter classes provide the functionality for doing this.
Patrick Healy
185
PrintWriter(Writer out) PrintWriter(Writer out, boolean autoFlush) PrintWriter(OutputStream out) PrintWriter(OutputStream out, boolean autoFlush)
Patrick Healy
186
print(Object o) print(String s) println(String s) print(char c) print(char[] cArray) print(int i) print(long l) print(float f) print(double d)
void print(boolean b)
Patrick Healy
187
Note:
On the previous slide, you may replace print with println in the various method definitions. The println method, which prints the object, is followed by a new line. When the object is passed to print or println, the objects toString( ) method converts it to a String object.
Patrick Healy
188
The next sample Java program creates a print stream, pw, of PrintWriter, wrapped on FileOutputStream, for text format.
pw = new PrintWriter(new FileOutputStream(tempFile),true);
The program creates the file, arg[0], if that file does not already exist. The program writes 10 random integers into the file by using the data output stream, then closes the stream. The data file could be viewed by using the type command in DOS
Patrick Healy
189
Patrick Healy
190
Patrick Healy
191
Patrick Healy
192
Patrick Healy
193
Patrick Healy
Patrick Healy
195
Print Streams
PrintWriter program
FileOutputStream args[0]
Patrick Healy
196
import java.io.IOException;
public class WriteToFile { public WriteToFile( ) { } // Empty constructor
Patrick Healy
197
Example: WriteToFile.java (continued) public static void main (String[ ] args) { File outputFileName = null; PrintWriter outToFile = null;
try { outputFileName = new File("outFile1.txt"); outToFile = new PrintWriter( new FileWriter(outputFileName)); // Now we can start writing to file outToFile.println("This message is going to the output file"); outToFile.println("This will be line two in the output file"); outToFile.println("We can write the output file any time we want"); outToFile.flush( ); // Flush output file }
Patrick Healy
ITP 120 Java Programming I
198
Example 18.6 catch (IOException ex) { System.out.println(Error: + ex.getMessage( ) ); System.out.println("There was a problem writing to the output file"); } finally { if ( outToFile != null ) outToFile.close( ); // Close output file } // End of finally block } // End of main method } // End of class WriteToFile
Patrick Healy
199
Patrick Healy
200
BufferedInputStream (InputStream in) BufferedInputStream (InputStream in, int bufferSize) BufferedOutputStream (OutputStream in) BufferedOutputStream (OutputStream in, int bufferSize) BufferedReader(Reader in) BufferedReader(Reader in, int bufferSize) BufferedWriter(Writer out) BufferedWriter(Writer out, int bufferSize)
Patrick Healy
201
This case study writes a program that views a text file in a text area. The user enters a filename in a text field and clicks the View button; the file is then displayed in a text area.
Patrick Healy
202
ViewFile program
// ViewFile.java: Read a text file and store it in a text area import java.awt.*; // Buffered I/O example (Demo program) import java.awt.event.*; import java.io.*; import javax.swing.*;
public class ViewFile extends MyFrameWithExitHandling implements ActionListener { // Button to view view private JButton jbtView = new JButton("View");
Patrick Healy
203
ViewFile program
// Text field to receive file name private JTextField jtf = new JTextField(12); // Text area to display file private JTextArea jta = new JTextArea(); public static void main(String [ ] args) // Main method { ViewFile frame = new ViewFile(); frame.setTitle("View File Program in Java"); frame.setSize(400, 300); frame.setVisible(true); }
Patrick Healy
204
ViewFile program
// Constructor public ViewFile() { // Panel p to hold a label, a text field, and a button Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(new Label("Filename"), BorderLayout.WEST); p.add(jtf, BorderLayout.CENTER); jtf.setBackground(Color.yellow); jtf.setForeground(Color.red); p.add(jbtView, BorderLayout.EAST);
Patrick Healy
205
ViewFile program
JScrollPane jsp = new JScrollPane(jtaFile); // Add jsp and p to the frame getContentPane().add(jsp, BorderLayout.CENTER); getContentPane().add(p, BorderLayout.SOUTH); // Register listener jbtView.addActionListener(this); }
Patrick Healy
206
ViewFile program
// Handle the "View" button public void actionPerformed(ActionEvent e) { if (e.getSource() == jbtView) showFile(); }
Patrick Healy
207
ViewFile program
// Use a BufferedStream to read text from the file BufferedReader infile = null; // Get file name from the input text field at the bottom String filename = jtf.getText().trim(); String inLine;
Patrick Healy
208
ViewFile program
infile = new BufferedReader(new FileReader(filename)); // Read a line inLine = infile.readLine(); boolean firstLine = true;
Patrick Healy
209
ViewFile program
while (inLine != null) // Append the line to the text area { if (firstLine) { firstLine = false; jtaFile.append(inLine); } else { jta.append("\n" + inLine); } inLine = infile.readLine(); } } // End of try block
Patrick Healy
210
ViewFile program
Patrick Healy
211
ViewFile program
ViewFile program
Demostrate the ViewFile program by running: java ViewFile (at the command prompt)
Wait for Java window to appear. then type Comcast1.txt or the name of some text file in the text box at the bottom of the Java window. Look at the contents on the text file in the Java window.
Patrick Healy
213
Patrick Healy
214
Patrick Healy
215
Patrick Healy
216
MyInput.java (full)
BufferedReader br
= new BufferedReader(new InputStreamReader(System.in), 1); // Declare and initialize the string String string = " "; // Get the string from the keyboard try { } { }
ITP 120 Java Programming I
217
MyInput.java (full)
// Read an int value from the keyboard public static int readInt() { return Integer.parseInt(readString()); }
Patrick Healy
218
MyInput.java (full)
// Read a double value from the keyboard public static double readDouble() { return Double.parseDouble(readString()); }
// Read a byte value from the keyboard public static double readByte() { return Byte.parseByte(readString()); }
Patrick Healy
219
MyInput.java (full)
// Read a short value from the keyboard public static double readShort() { return Short.parseShort(readString()); }
// Read a long value from the keyboard public static double readLong() { return Long.parseLong(readString()); }
Patrick Healy
220
MyInput.java (full)
Patrick Healy
221
Patrick Healy
222
The name of the file is passed in filename The term access determines what type of file access is permitted. If the access is r, the file is read-only. If the access is rw, the file is opened in read-write mode.
Patrick Healy
223
The method seek ( ) is used to set the current position of the file pointer within a random access file:
void seek (long newpos) throws IOException
newpos specifies the new position, in bytes, of the file pointer from the beginning of the file. After a call to seek( ), the next read or write operation will occur at the new file position.
Patrick Healy
224
public long length ( ) throws IOException Returns the length of the file in bytes. public final void writeChar (int v) throws IOException Writes a character to the file as a 2-byte Unicode character with the higher byte written first. public final void writeChars(String s) throws IOException Writes a string to a file as a sequence of characters.
Patrick Healy
225
access file I/O. The program writes 6 double numbers to a file and
then reads them back in a non-sequential order.
Patrick Healy
226
RandonAccessDemo.java
public class RandomAccessDemo { public static void main(String[ ] args) throws IOException { double data[ ] = { 19.4, 10.1, 123.54, 33.0, 87.9, 74.25 }; double d; RandomAccessFile raf;
Patrick Healy
227
raf = new RandomAccessFile("random.dat", "rw"); } catch(FileNotFoundException ex) { System.out.println("Cannot open file."); System.out.println(Error: + ex.getMessage( ) ); return ; }
Patrick Healy
228
// Write values to the file. for (int i=0; i < data.length; i++) { try { raf.writeDouble(data[i]); } catch(IOException ex) { System.out.println(Error: + ex.getMessage( )); System.out.println("Error writing to file."); return ; } } // End of for loop
Patrick Healy
229
d = raf.readDouble();
System.out.println("First value is " + d); raf.seek(8); // seek to second double d = raf.readDouble(); System.out.println("Second value is " + d); raf.seek(8 * 3); // seek to fourth double d = raf.readDouble(); System.out.println("Fourth value is " + d); System.out.println();
Patrick Healy
ITP 120 Java Programming I
230
Patrick Healy
231
System.out.println(Error: + exc.getMessage( ) ); System.out.println("Error seeking or reading."); } raf.close( ); // Close the file } // End of main ( ) } // End of class RandomAccessDemo
Patrick Healy
232
First value is 19.4 Second value is 10.1 Fourth value is 33.0 Here is every other value: 19.4 123.54 87.9
Patrick Healy
233
Now let us use RandomAccessFile to create a useful project for storing and viewing and address book. The user interface of the program is shown in Figure 16.24. The Add button stores a new address to the end of the file. The First, Next, Previous, and Last buttons retrieve the first, next, previous, and last addresses from the file, respectively.
Patrick Healy
234
Patrick Healy
235
Constants
Patrick Healy
236
Variables
(token type)
int ttype
Contains the current token type, which matches one of the constants listed on the preceding slide.
double nval Contains the value of the current token if that token is a number. String sval Contains a string that gives the characters of the current token if that token is a word.
Patrick Healy
237
Methods
IOException
Parses the next token from the input stream of this StreamTokenizer. The type of the next token is returned in the ttype field. If ttype == TT_WORD, the token is stored in sval; if ttype == TT_NUMBER, the token is stored in nval.
Patrick Healy
238
Patrick Healy
239
ParsingTextFile.java
(Demo program)
// ParsingTextFile.java: ITP 120 // Process text file using StreamTokenizer Chapter 18 I/O import java.io.*;
public class ParsingTextFile { // Main method public static void main(String[] args) { // Declare file reader and writer character (2 bytes) streams FileReader frs = null; FileWriter fws = null; // Declare streamTokenizer StreamTokenizer in = null;
Patrick Healy
240
ParsingTextFile.java
// Declare a print stream PrintWriter out = null;
(Demo)
// For input file fields: student name, midterm1, // midterm2, and final exam score String sname = null; double midterm1 = 0; double midterm2 = 0; double finalScore = 0;
// Computed total score double total = 0; try { // Create file input and output streams frs = new FileReader("grades.dat"); fws = new FileWriter("gradesout.dat");
Patrick Healy
241
ParsingTextFile.java
(Demo)
// Create a stream tokenizer wrapping file input stream in = new StreamTokenizer(frs); out = new PrintWriter(fws); // Create PrintWriter object // Read first token in.nextToken(); // Process a record // TTs are Tokenizer constants while (in.ttype != in.TT_EOF) // TT_EOF means end of file { // Get student name if (in.ttype == in.TT_WORD) // TT_WORD means token is a word sname = in.sval; else System.out.println("Bad file format");
Patrick Healy
ITP 120 Java Programming I
242
ParsingTextFile.java
(Demo)
// Get midterm1 if (in.nextToken() == in.TT_NUMBER) //TT_NUMBER means token is a number midterm1 = in.nval; else System.out.println("Bad file format"); // Get midterm2 score if (in.nextToken() == in.TT_NUMBER) midterm2 = in.nval; else System.out.println("Bad file format"); // Get final exam score if (in.nextToken() == in.TT_NUMBER) finalScore = in.nval;
Patrick Healy
ITP 120 Java Programming I
243
ParsingTextFile.java
(Demo)
total = midterm1*0.3 + midterm2*0.3 + finalScore*0.4; out.println(sname + " " + total); in.nextToken( ); } } catch (FileNotFoundException ex) { System.out.println("Error: " + ex.getMessage()); System.out.println("File not found: in.dat"); } catch (IOException ex) { System.out.println(ex.getMessage()); }
Patrick Healy
ITP 120 Java Programming I
244
ParsingTextFile.java
(Demo)
finally // Always execute finally block { try { if (frs != null) frs.close(); if (fws != null) fws.close(); } catch (IOException ex) { System.out.println(ex); } } System.out.println("To view input file, TYPE GRADES.DAT"); System.out.println("To view output file, TYPE GRADESOUT.DAT"); } // End of main method } // End of class
Patrick Healy
245
Patrick Healy
246
Patrick Healy
247
TestFileWriter.java
TestObjectStreamForArray.java TestObjectInputStream.java TestObjectOutputStream.java AddressBook.java (with FixedLengthStringIO.java) Other created or required files: object.dat, temp.txt, student.dat
Patrick Healy
248
End of Presentation
Patrick Healy
249