Java As An Object-Oriented Programming Language
Java As An Object-Oriented Programming Language
Java as an Object-oriented
Programming Language
Java IO Stream
Files
2
Storage
Why so many?
Because they behave differently!
3
Memory vs. Disk
Typical Properties
Memory Disk
Capacity: 1-4 Gb >100 Gb
When power goes off: Data is lost Data is safe
When program ends: Data is lost Data is safe
Sequential access
1.2 GB / second 50 MB / second
speed:
Random access ??
1.2 GB / second
Tradeoff:
speed: ~ 66.7 seeks / second
Disks have greater capacity (more GB) and offer permanent storage;
Memory is much faster.
4
Files and Directories
tmp Hello.java
super3
C: Documents
and Settings All Users
Adobe
Program Files
…
WinShell
Files and Variables
Recall variables:
They have types, names, and a location in memory
You can put data inside them, and use the data later
Read
Move data from a file on the disk into a variable (or
variables) in memory
Write
Move data from a variable (or variables) in memory to a file
on the disk
import java.io.*;
8
Reading data from text files
Example:
Scanner input = new Scanner(new File("numbers.txt"));
9
Compiler error with files
10
Exceptions
Examples:
Trying to read a file that does not exist.
Dividing by 0.
Using charAt(10) on a string of length 5.
11
Checked exceptions
12
throws clause: How to waive your
rights
throws clause: Tells the compiler that a method
may throw an exception.
Like a waiver of liability:
"I hereby agree that this method might throw an exception,
and I accept the consequences (crashing) if this happens."
Example:
public static void main(String[] args)
throws FileNotFoundException {
13
Patched code
14
Recap: Tokens
The Scanner breaks apart the input into tokens. It will interpret
the tokens in different ways depending on if you call next(),
nextInt(), or nextDouble().
Token Type(s)
1. 23 int, double, String
2. 3.14 double, String
3. "John String
4. Smith" String
15
The input cursor
16
Consuming tokens
input.nextDouble();
308.2\n 14.9 7.4 2.8\n\n\n3.9 4.7 -15.4\n2.8\n
^
input.nextDouble();
308.2\n 14.9 7.4 2.8\n\n\n3.9 4.7 -15.4\n2.8\n
^
17
Exercise: Version 1
Consider an input file named input.txt:
308.2
14.9 7.4 2.8
Write a program that reads the first 5 values from this file and prints
them along with their sum.
Output:
number = 308.2
number = 14.9
number = 7.4
number = 2.8
number = 3.9
Sum = 337.19999999999993
18
Solution: Version 1
// Displays the first 5 numbers in the given file,
// and displays their sum at the end.
19
Reading a whole file
20
Look before you read
Output:
number = 308.2
number = 14.9
number = 7.4
number = 2.8
number = 3.9
number = 4.7
number = -15.4
number = 2.8
Sum = 329.29999999999995
22
Solution: Version 2
// Displays each number in the given file,
// and displays their sum at the end.
23
Exercise: Version 3
308.2 hello
14.9 7.4 bad stuff 2.8
24
Solution: Version 3
// Displays each number in the given file,
// and displays their sum at the end.
25
Line-based processing
26
Who's next in line?
27
Reading between the newlines
input.nextLine()
23\t3.14 John Smith\t"Hello world"\n\t\t45.2 19\n
^
input.nextLine()
23\t3.14 John Smith\t"Hello world"\n\t\t45.2 19\n
^
Input:
Hey Prof. Yates,
I would like to know more about files. Please explain them to me.
Sincerely,
Susie Q. Student
Output:
> Hey Prof. Yates,
> I would like to know more about files. Please explain them to me.
> Sincerely,
> Susie Q. Student
29
Solution
import java.io.*;
import java.util.*;
30
Example
31
Line-based or token-based?
32
Scanners on Strings
A Scanner can be constructed to tokenize a particular
String (such as one line of an input file).
Example:
String text = "1.4 3.2 hello 9 27.5";
Scanner scan = new Scanner(text); // five tokens
33
Tokenizing lines
34
Multi-line records
Erica Kane
3 2.8 4 3.9 3 3.1
Greenlee Smythe
3 3.9 3 4.0 4 3.9
Ryan Laveree, Jr.
2 4.0 3 3.6 4 3.8 1 2.8
36
Outputting text to files
Example:
PrintWriter output = new PrintWriter(new File("output.txt"));
output.println("Hello, file!");
output.println("This is a second line of output.");
37
Common Courtesy
Example:
PrintWriter out = new PrintWriter(“output.txt”);
out.println(“Hello, output file!”);
out.close();
while (input.hasNextLine()) {
output.println(input.nextLine());
}
input.close();
output.close();
}
}
39
Binary File I/O
Not all files are text files
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
43
Reading binary data from files
Example:
PrintStream output = new PrintStream(new File("output.txt"));
output.println("Hello, file!");
output.println("This is a second line of output.");
Or
46
PrintStream warning
Caution: Do not open a file for reading (Scanner)
and writing (PrintStream) at the same time.
You could overwrite your input file by accident!
47
Exercise
48
Solution
public class BinaryCopier {
public static void main(String [] args)
throws FileNotFoundException, IOException
{
Scanner kb = new Scanner(System.in);
String name1 = kb.next();
String name2 = kb.next();
FileInputStream input =
new FileInputStream(new File(name1));
PrintStream output =
new PrintStream(new File(name2));
49
FilterInputStream/FilterOutputStream
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream 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. 50
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 BufferedOutputStream
ObjectOutputStream PrintStream
51
DataInputStream
DataInputStream extends FilterInputStream
and implements the DataInput interface.
InputStream java.io.DataInput
52
BufferedInputStream/BufferedOutputStream
Using buffers to speed up I/O
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
53
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
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
54
ObjectInputStream
ObjectInputStream extends InputStream and
implements ObjectInput and ObjectStreamConstants.
java.io.InputStream ObjectStreamConstants
java.io.DataInput
java.io.ObjectInputStream java.io.ObjectInput
55
ObjectOutputStream
ObjectOutputStream extends OutputStream and
implements ObjectOutput and ObjectStreamConstants.
java.io.OutputStream ObjectStreamConstants
java.io.DataOutput
java.io.ObjectOutputStream java.io.ObjectOutput
56
The Serializable Interface
Not all objects can be written to an output stream.
Objects that can be written to an object stream is said to be serializable.
A serializable object is an instance of the java.io.Serializable interface.
So the class of a serializable object must implement Serializable.
57
The transient Keyword
If an object is an instance of Serializable, but it
contains non-serializable instance data fields, can the
object be serialized?
The answer is no.
To enable the object to be serialized, you can use
the transient keyword to mark these data fields to tell
the JVM to ignore these fields when writing the object
to an object stream.
58
The transient Keyword, cont.
Consider the following class:
public class Foo 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 Foo 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.
59
Random Access Files
All of the streams you have used so far are known as
read-only or write-only streams.
The external files of these streams are sequential files
that cannot be updated without creating a new file.
It is often necessary to modify files or to insert new
records into files. Java provides the RandomAccessFile
class to allow a file to be read from and write to at random
locations.
60
RandomAccessFile
DataInput DataInput
java.io.RandomAccessFile
+RandomAccessFile(file: File, mode: Creates a RandomAccessFile stream with the specified File object and
String) mode.
+RandomAccessFile(name: String, Creates a RandomAccessFile stream with the specified file name
mode: String) string and mode.
+close(): void Closes the stream and releases the resource associated with the stream.
+getFilePointer(): long Returns the offset, in bytes, from the beginning of the file to where the
next read or write occurs.
+length(): long Returns the length of this file.
+read(): int Reads a byte of data from this file and returns –1 an the end of stream.
+read(b: byte[]): int Reads up to b.length bytes of data from this file into an array of bytes.
+read(b: byte[], off: int, len: int) : int Reads up to len bytes of data from this file into an array of bytes.
+seek(long pos): void Sets the offset (in bytes specified in pos) from the beginning of the
stream to where the next read or write occurs.
+setLength(newLength: long): void Sets a new length of this file.
+skipBytes(int n): int Skips over n bytes of input discarding the skipped bytes.
+write(b: byte[]): void Writes b.length bytes from the specified byte array to this file, starting
+write(byte b[], int off, int len) at the current file pointer.
+write(b: byte[], off: int, len: int): Writes len bytes from the specified byte array starting at offset off to
void this file.
61
RandomAccessFile Methods
62
RandomAccessFile Methods, cont.
void seek(long pos) throws IOException;
Sets the offset from the beginning of the
RandomAccessFile stream to where the next read
or write occurs.
63
RandomAccessFile Methods, cont.
long length()IOException
Returns the length of the file.