30
COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

  • View
    221

  • Download
    1

Embed Size (px)

Citation preview

Page 1: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Java Programming

Topic 6: Streams and Files

Reading: Chapter 12

Page 2: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 2

Outline

Introduction and overview

Writing and reading text files

Writing and reading binary files

Writing and reading objects

File management

Page 3: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 3

Introduction and Overview When talking about IO, we need to consider files

Location:– blocks of main memory– local file system– over the net

Format:– text or binary– zipped or not zipped

Access mode:– plain sequential, – buffered, – pushback, – Random

Java has classes for all possible combinations.

Page 4: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 4

Introduction and Overview Java streams provide an abstraction of files at different locations:

Local files and files from the net are handled in essentially the same way. In this lecture, we deal with only files on local machine.

Java has many (60+) stream classes for various file formats and access modes

We will cover only a few commonly used classes.

What follows is an overview of those 60+ classes. Classes for reading text files Classes for writing text files Classes for reading binary files Classes for writing binary files

Page 5: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 5

Reader All classes for reading from text files descend from the abstract

class Reader Reader has an method read, which returns the next unicode

character or –1 (EOF)

Reader

LineNumberReader

PushbackReader

InputStreamReader

CharArrayReader

FilterReader

BufferedReader

StringReader

PipedReader

FileReader

Page 6: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 6

Writer All classes for writing to text files descend from the abstract

class Writer Writer has an method write(int b), which writes a

unicode character to an output

Writer

PrintWriter

FileWriter

BufferedWriter

OutputStreamWriter

PipedWriter

FilterWriter

CharArrayWriter

StringWriter

Page 7: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 7

InputStream All classes for reading from binary files descend from the

abstract class InputStream InputStream has one abstract method read, which returns

the next byte character or –1 (EOF)

InputStream

PushbackInputStream

LineNumberInputStream

DataInputStream

BufferedInputStream

FileInputStream

ByteArrayInputStream

FilterInputStream

SequenceInputStream

StringBufferInputStream

ObjectInputStream

PipedInputStream

. . . .

Page 8: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 8

OutputStream All classes for writing to binary files descend from abstract class

OutputStream OutputStream has one abstract method write(int b),

which writes one byte to an output

OutputStream

CheckedOutputStream

PrintStreamData

OutputStreamBuffered

OutputStream

ByteArrayOutputStream

FilterOutputStream

ObjectOutputStream

PipedOutputStream

. . . .

FileOutputStream

Page 9: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 9

Writing Text Output Writing to a text file:

Open a file for writing FileWriter f = new FileWriter(“employee.dat”);

The FileWriter class has method, namely write, for writing contents of stream f to file “employee.dat”.

But it has no methods for putting information into the stream.

Solution: nest FileWriter with PrintWriter PrintWriter out = new PrintWriter(f);

Now you can use methods of PrintWriter out.print(…), out.println(…)//DataFileTest.java

Page 10: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 10

Writing Text Output Java uses Unicode characters: 2 bytes for each character. User’s system might use a different encoding. E.g. Windows

uses ISO 8859-1, i.e. ANSI code. Potential mismatch automatically dealt with by FileWriter1. To be more precise, FileWriter is a combination of

OutputStreamWriter and FileOutputStream. FileWriter f = new FileWriter(“employee.dat”);is equivalent to

OutputStreamWriter f = new OutputStreamWriter( new FileOutputStream(“employee.dat”));

2. OutputStreamWriter resolves the potential mismatch.3. User can choose other encoding using new OutputStreamWriter(OutputStream, “Big5”)

Page 11: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 11

Writing Text OutputMore Notes:

Attempts to write to a file might result in IOException when, e.g., file system full or no write permission. As such, one needs deal with exceptions(either use the try/catch blocks or throw).

PrintWriters are always buffered. close stream after use to flush out the the last bits. Can manually flush buffer using the flush method. Import java.io.*.

System.out is a predefined OutputStreamWriter, stands for screen.

Page 12: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 12

Writing Text Output public void writeData(PrintWriter out) throws

IOException { GregorianCalendar calendar = new GregorianCalendar(); calendar.setTime(hireDay); out.println(name + "|" + salary + "|" + calendar.get(Calendar.YEAR) + "|" + (calendar.get(Calendar.MONTH) + 1) + "|" + calendar.get(Calendar.DAY_OF_MONTH)); }

Page 13: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 13

Reading Text Input Reading a text file:

Open a file for reading FileReader f = new FileReader(“employee.dat”);

Nest FileReader with BufferedReader so that you can extract information from stream f.

BufferedReader in = new BufferedReader(f);

Now you can read lines in input as strings in.readLine();

Might throw IOException.

DataFileTest.java

Page 14: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 14

Reading Text Input Reading a text file / Parsing input

s = readLine() gives you a long string.

Need to break the string into individual strings and convert them into proper type.

To do this, use the StringTokenizer class in java.util.

Create a StringTokenizer object for the delimiter “|” StringTokenizer t = new StringTokenizer(s, “|”);

Page 15: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 15

Reading Text Input Reading a text file / Parsing input

Use the nextToken method to extract the next piece from string.

t.nextToken() --- name. t.nextToken() --- salary as string. Needs Double.parseDouble t.nextToken() --- year as string. Needs Integer.parseInt t.nextToken() --- month as string. Needs Integer.parseInt t.nextToken() --- day as string. Needs Integer.parseInt

Here we know that there are 5 tokens on each line. In general, call t.hasMoreTokens before each

t.nextToken

DataFileTest.java

Page 16: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 16

Reading Text Input public void readData(BufferedReader in) throws

IOException { String s = in.readLine(); StringTokenizer t = new StringTokenizer(s, "|"); name = t.nextToken(); salary = Double.parseDouble(t.nextToken()); int y = Integer.parseInt(t.nextToken()); int m = Integer.parseInt(t.nextToken()); int d = Integer.parseInt(t.nextToken()); GregorianCalendar calendar = new GregorianCalendar(y, m - 1, d); // GregorianCalendar uses 0 = January hireDay = calendar.getTime(); } //DataFileTest.java

Page 17: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 17

Reading From the KeyboardSystem.in is a predefined InputStreamReader, stands for

keyboard.import java.io.*;

public class Echo { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); String s; while((s = in.readLine()).length() != 0) System.out.println(s); // An empty line terminates the program }} //Echo.java

Page 18: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 18

Writing Binary Files Open a binary file for writing FileOutputStream out = new FileOutputStream(“employee.dat”); Writing to a binary file byte b = 0; out.write( b ); // write a byte appears as 00

Writing to a binary file out.write(int b); Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written

is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored. -- JDK 1.3 --

Page 19: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 19

Writing Binary Files Suppose we want to write double, int, string, etc… to a binary

file in buffered mode.

Open binary file for writing as follows: DataOutputStream out = new DataOutputStream( new BufferedOutputStream(

new FileOutputStream("employee.dat"))); Now we can write simply using: out.writeChars( name + "\n" ); out.writeDouble(salary); GregorianCalendar calendar = new GregorianCalendar(); calendar.setTime(hireDay); out.writeInt(calendar.get(Calendar.YEAR)); out.writeInt(calendar.get(Calendar.MONTH) + 1); out.writeInt(calendar.get(Calendar.DAY_OF_MONTH));//BinaryFileTest.java

Page 20: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 20

Reading Binary Files Open a binary file for reading FileInputStream in = new FileInputStream(“employee.dat”); byte c = in.read(); // read a byte Reading from a binary file int in.read(); Reads the next byte of data from the input stream. The value byte is returned

as an int 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. -- JDK 1.3 –

Programs seldom read and write bytes. Combine with subclasses of FilterInputStream and FilterOutputStream (see slides 7 and 8) to construct desired streams.

Page 21: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 21

Reading Binary Files To read double, int, string, etc … from a binary file in buffered

mode, open binary file for reading as follows: DataInputStream in = new DataInputStream( new BufferedInputStream(

new FileInputStream("employee.dat"))); Now we can read by using: name = in.readLine() salary = in.readDouble(); int y = in.readInt(); int m = in.readInt(); int d = in.readInt(); GregorianCalendar calendar=new GregorianCalendar(y, m - 1,d); hireDay = calendar.getTime();

//BinaryFileTest.java

//No need for StringTokenizer

Page 22: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 22

Writing and Reading Objects Tedious to do manually.

Java provides a mechanism called object serialization that makes this straightforward.

To save and read objects of a class, the class must implement the Serializable interface.class Employee implements Serializable { ….}

Serializable has no methods. It is just a tag.

Not all classes are made serializable for security reasons.(P742)

Page 23: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 23

Writing Objects To save an object, open an ObjectOutputStream ObjectOutputStream out =

new ObjectOutputStream ( new FileOutputStream(“employee.dat”));

Simply use writeObject method to save an object Employee harry = new Employee("Harry Hacker", 35000, 1989,10,1); Manager carl = new Manager("Carl Cracker", 75000, 1987,12,15); out.writeObject(harry); out.writeObject(carl);

If a superclass implements Serializable, a subclass does this automatically.

Page 24: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 24

Reading Objects To get back an object, open an ObjectInputStream ObjectInputStream in = new ObjectInputStream ( new FileInputStream(“employee.dat”));

Use readObject method to retrieve objects in the same order in which they were written

Employee[] newStaff = (Employee[]) in.readObject(); Cast necessary because readObject returns an object of class

Object.

Strings and arrays can be handled this way since they are objects

//ObjectFileTest.java

Page 25: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 25

Writing and Reading Objects The above scheme works even when objects have reference field.

Example:

class Manager extend Employee { …

private Employee secretary; } Employee harry = new Employee( …); Manager carl = new Manager(…); carl.setSecretary(harry); Manager tony = new Manager(…); tony.setSecretary(harry);

secretary secretary

carl tony

harry

Page 26: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 26

Writing and Reading Objects The following does not save three copies of harry out.writeObject(carl);

out.writeObject(harry); out.writeObject(tony);

Here is what really happens: Each object gets a unique serial number (1, 2, ..) When saving an object, find out whether the same object has

already been stored. If yes, just write “same as previously saved object with serial

number x”. Reading reverse the procedure. All these are done automatically.

//ObjectRefTest.java

Page 27: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 27

A Diversion/Using serialization for cloning

Idea Write an object to an output stream

out.writeObject(someObeject) Read it back in

copy = in.readObject()

Note: No need to write the object to a file. Write it to a byte array (an internal buffer) using ByteArrayOutputStream

Page 28: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 28

ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out= new ObjectOutputStream(bout); out.writeObject(someObject); out.close(); // read a clone of the object from the byte array ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream in = new ObjectInputStream(bin); Object copyOfObject = in.readObject(); in.close();

//SerialCloneTest.java

A Diversion/Using serialization for cloning

bout.toByteArray(): creates byte array and copy contents over

Page 29: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 29

File Management Use java.io.File:

A File object can represent either a file or a directory. Use the isDirectory and isFile methods to find out.

Creating a new directory:1. Create a File object

1.File tempDir = new File( “temp”);

2. Make it a directory

1.tempDir.mkdir();

Inspecting contents of a directory tempDir.list() returns an array of file names under the

directory

Page 30: COMP201 Java Programming Topic 6: Streams and Files Reading: Chapter 12

COMP201 Topic 6 / Slide 30

File Management Creating a new file

1. Create a File object:File foo = new File(“dirName”+File.separator +

“data.txt”);File foo = new File(“dirName”, “data.txt”);

2. Create file1.foo.createNewFile(): creates a file if no file with that

name exists;

Deleting files and directoriessomeDir.delete();someFile.delete();

//FindDirectories.java