Java I/O L. Grewe. Overview of java.io methods for accessing file, text data, object serialization...

50
Java I/O Java I/O L. Grewe L. Grewe

Transcript of Java I/O L. Grewe. Overview of java.io methods for accessing file, text data, object serialization...

Java I/OJava I/O

L. GreweL. Grewe

Overview of java.ioOverview of java.io methods for accessing file, text data, methods for accessing file, text data,

object serialization and object serialization and internationalization internationalization

Sequential and Random access Sequential and Random access Reading and writing of primitive values Reading and writing of primitive values Applications and applets are provided Applications and applets are provided

with three streams automatically with three streams automatically System.out (output stream) System.out (output stream) System.in (input stream) System.in (input stream) System.err (error streamSystem.err (error stream

Uses StreamsUses Streams Two kinds of basic streams: Two kinds of basic streams:

1. 1. bytebyte based based streamsstreams 8 bits, data-based8 bits, data-based input streams and output streamsinput streams and output streams

2. character2. character based based streamsstreams 16 bits, text-based16 bits, text-based readers and writersreaders and writers

Byte StreamsByte Streams Two parent Two parent abstractabstract classes: classes: InputStreamInputStream and and OutputStreamOutputStream Reading bytes:Reading bytes:

• InputStreamInputStream class defines an abstract method class defines an abstract methodpublic abstract int read() throws IOExceptionpublic abstract int read() throws IOException

Designer of a concrete input stream class overrides this method to provide Designer of a concrete input stream class overrides this method to provide useful functionality. useful functionality.

E.g. in the E.g. in the FileInputStreamFileInputStream class, the method reads one byte from a file class, the method reads one byte from a file• InputStreamInputStream class also contains nonabstract methods to read an array class also contains nonabstract methods to read an array

of bytes or skip a number of bytesof bytes or skip a number of bytes Writing bytesWriting bytes::

• OutputStreamOutputStream class defines an abstract method class defines an abstract methodpublic abstract void write(int b) throws IOExceptionpublic abstract void write(int b) throws IOException

• OutputStreamOutputStream class also contains nonabstract methods for tasks such class also contains nonabstract methods for tasks such as writing bytes from a specified byte arrayas writing bytes from a specified byte array

Close the stream after reading of writing to it to free up limited Close the stream after reading of writing to it to free up limited operating system resources by using operating system resources by using close()close()

Byte Streams (Binary Streams)…Byte Streams (Binary Streams)…some of the hierarchysome of the hierarchy

Object

InputStream

FileInputStream

FilterInputStreamBufferedInputStream

FilterOutputStream

FileOutputStream

BufferedOutputStream

DataInputStream

OutputStream

DataOutputStream

PrintStream

Byte Stream some of the Byte Stream some of the hierarchyhierarchy

InputStream

AutioInputStream

FileInputStream

ObjectInputStream

SequenceInputStream

ByteArrayInputStream

PipedInputStream

FilterInputStream

Java Programming Java Programming

Byte StreamsByte Streams

OutputStream

FileOutputStream

ObjectOutputStream

ByteArrayOutputStream

PipeOutputStream

FilterOutputStream

Byte StreamsByte Streamsimport java.io.*;import java.io.*;

public class CountBytes {public class CountBytes { public static void main(String[] args) public static void main(String[] args) throws IOExceptionthrows IOException {{ InputStreamInputStream in; in; if (args.length == 0)if (args.length == 0) in = System.in;in = System.in; else else in = new FileInputStream(args[0]);in = new FileInputStream(args[0]);

int total = 0;int total = 0; while (in.read() != -1)while (in.read() != -1) total++;total++; System.out.println(total + " bytes");System.out.println(total + " bytes"); }}}}

The abstract class InputStream declares methods to read bytes from a particular source.

Reads a single byte of data and returns the byte that was read, as an integer in the range 0 to 255, not -128 to 127(unsigned).

Type is InputStream

Example code1: Example code1: import java.io.*;import java.io.*;class CountBytes {class CountBytes {

public static void main(String[] args) throws IOException {public static void main(String[] args) throws IOException { FileInputStream in = new FileInputStream(args[0]);FileInputStream in = new FileInputStream(args[0]); int total = 0;int total = 0; while (while (in.readin.read() != -1)() != -1) total++; total++; in.close();in.close(); System.out.println(total + ” bytes”);System.out.println(total + ” bytes”);}}

}}

Example code2: Example code2: import java.io.*;import java.io.*;class TranslateByte {class TranslateByte { public static void main(String[] args) throws IOException {public static void main(String[] args) throws IOException { byte from = (byte)args[0].charAt(0);byte from = (byte)args[0].charAt(0); byte to = (byte)args[1].charAt(0);byte to = (byte)args[1].charAt(0); int x;int x; while((x = while((x = System.in.readSystem.in.read()) != -1)()) != -1) System.out.writeSystem.out.write(x == from ? to : x);(x == from ? to : x);

}}}}

If you run If you run “java TranslateByte b B” “java TranslateByte b B” and enter text and enter text bigboybigboy via the via the keyboard the output will be: keyboard the output will be: BigBoy!BigBoy!

Byte Stream - outputByte Stream - output

Byte Stream - OutputByte Stream - Output

import java.io.*;import java.io.*;

public class TranslateByte {public class TranslateByte { public static void main(String[] args) public static void main(String[] args) throws IOExceptionthrows IOException {{ byte from = (byte) args[0].charAt(0);byte from = (byte) args[0].charAt(0); byte to = (byte) args[1].charAt(0);byte to = (byte) args[1].charAt(0); int b;int b; while ((b = System.in.read()) != -1)while ((b = System.in.read()) != -1) System.outSystem.out.write(b == from ? to : b);.write(b == from ? to : b); }}}}

The abstract class OutputStream provides an abstraction for writing bytes to a destination.

Run:Java TranslateByte b B

Result: (input abracadabra!)aBracadaBra!

Type is PrintStream

Character streamsCharacter streams Two parent Two parent abstractabstract classes for characters: classes for characters: ReaderReader and and

WriterWriter. Each support similar methods to those of its byte . Each support similar methods to those of its byte stream counterpartstream counterpart–InputStream–InputStream and and OutputStreamOutputStream, , respectivelyrespectively

The standard streams—The standard streams—System.inSystem.in, , System.outSystem.out and and System.errSystem.err—existed before the invention of character —existed before the invention of character streams. So they are byte streams though logically they streams. So they are byte streams though logically they should be character streams. should be character streams.

Character Streams - ReadingCharacter Streams - Reading

Reader

BufferedReader

InputStreamReader

StringReader

CharArrayReader

PipedReader

FilterReader

Character Streams - WritingCharacter Streams - Writing

Writer

BufferedWriter

OutputStreamWriter

StringWriter

CharArrayWriter

PipedWriter

FilterWriter

PrintWriter

Conversion between byte and character streamsConversion between byte and character streams The conversion streams The conversion streams InputStreamReaderInputStreamReader and and

OutputStreamReaderOutputStreamReader translate between Character and byte translate between Character and byte streamsstreams• public InputStreamReader(InputStream in)public InputStreamReader(InputStream in)• public InputStreamReader(InputStream in, String encoding)public InputStreamReader(InputStream in, String encoding)• public OutputStreamWriter(OutputStream out)public OutputStreamWriter(OutputStream out)• public OutputStreamWriter(OutputStream out, String public OutputStreamWriter(OutputStream out, String

encoding)encoding)

readread method of method of InputStreamReaderInputStreamReader read bytes from their read bytes from their associated associated InputStreamInputStream and convert them to characters and convert them to characters using the appropriate encoding for that streamusing the appropriate encoding for that stream

writewrite method of method of OutputStreamWriterOutputStreamWriter take the supplied take the supplied characters, convert them to bytes using the appropriate characters, convert them to bytes using the appropriate encoding and write them to its associated encoding and write them to its associated OutputStreamOutputStream

Closing the conversion stream also closes the associated Closing the conversion stream also closes the associated byte stream – may not always desirablebyte stream – may not always desirable

Character Stream Example Character Stream Example import java.io.*;import java.io.*;

public class CountSpace {public class CountSpace { public static void main(String[] args) public static void main(String[] args) throws IOExceptionthrows IOException {{ ReaderReader in; in; if (args.length == 0)if (args.length == 0) in = new in = new InputStreamReaderInputStreamReader(System.in);(System.in); else else in = new in = new FileReaderFileReader(args[0]);(args[0]);

int ch;int ch; int total;int total; int spaces = 0;int spaces = 0; for (total = 0; (ch = in.read()) != -1; total++) {for (total = 0; (ch = in.read()) != -1; total++) { if (Character.isWhitespace((char) ch))if (Character.isWhitespace((char) ch)) spaces++;spaces++; }} System.out.println(total + " chars "System.out.println(total + " chars " + spaces + " spaces");+ spaces + " spaces"); }}}}

The abstract classes for reading and writing streams of characters are Reader and Writer.

Run:Java CountSpace CountSpace.javaResult: 520 characters 172 spaces

The abstract class Reader provides a character stream analogous to the byte stream InputStream and the methods of Reader essentially mirror those of InputStream.

The conversion streams InputStreamReader and OutputStreamWriter translate between character and byte streams using either a specified character set encoding or the default encoding for the local system.

Reading from a StreamReading from a Stream The basic read() method reads a byte at a time. The basic read() method reads a byte at a time.

Some other methods that read more than 1 byteSome other methods that read more than 1 byte• public int read(byte[] data) throws IOException public int read(byte[] data) throws IOException

Tries to read enough bytes to fill the array dataTries to read enough bytes to fill the array data

• public int read(byte[] data, int offset, int length) throws public int read(byte[] data, int offset, int length) throws IOException IOException

Tries to read length bytes from stream and store in data[] at starting index Tries to read length bytes from stream and store in data[] at starting index offsetoffset

• These methods then return the number of bytes actually read. You These methods then return the number of bytes actually read. You should not assume that the array will be filled or that length bytes will should not assume that the array will be filled or that length bytes will actually have been read. If the end of stream is encountered, -1 is actually have been read. If the end of stream is encountered, -1 is returnedreturned

ReadingReading

Use other classes with richer Use other classes with richer methods (i.e. DataInputStream) to methods (i.e. DataInputStream) to read in different data typesread in different data types

WritingWriting abstract  void abstract  void write(char[] cbuf, int off, int len) (char[] cbuf, int off, int len)

          Write a portion of an array of characters.            Write a portion of an array of characters.  void void write(int c) (int c)

          Write a single character. void          Write a single character. voidwritewrite(String str) (String str)           Write a string. void          Write a string. voidwritewrite(String str, int off, int len) (String str, int off, int len)           Write a portion of a string.          Write a portion of a string.

Other methods – for byte based – print*(*)Other methods – for byte based – print*(*) abstract  void abstract  void closeclose() ()

          Close the stream, flushing it           Close the stream, flushing it abstract  void abstract  void flushflush() ()

          Flush the stream. void          Flush the stream. voidwritewrite(char[] cbuf) (char[] cbuf)           Write an array of characters.           Write an array of characters.

File I/O : The File I/O : The FileFile class class The The FileFile class is particularly useful for retrieving information class is particularly useful for retrieving information

about a file or a directory from a disk.about a file or a directory from a disk.• A A FileFile object actually represents a path, not necessarily an object actually represents a path, not necessarily an

underlying fileunderlying file• A A FileFile object doesn’t open files or provide any file-processing object doesn’t open files or provide any file-processing

capabilitiescapabilities Three constructorsThree constructors

• public File( String name)public File( String name)• public File( String pathToName, String name)public File( String pathToName, String name)• public File( File directory, String name)public File( File directory, String name)

Main methodsMain methods• boolean canRead() / boolean canWrite()boolean canRead() / boolean canWrite()• boolean exists()boolean exists()• boolean isFile() / boolean isDirectory() / boolean boolean isFile() / boolean isDirectory() / boolean

isAbsolute()isAbsolute()• String getAbsolutePath() / String getPath()String getAbsolutePath() / String getPath()• String getParent()String getParent()• String getName()String getName()• long length()long length()• long lastModified()long lastModified()

File I/OFile I/O

Sequential-Access file: the Sequential-Access file: the FileFile streams— streams—FileInputStreamFileInputStream, , FileOutputStreamFileOutputStream, , FileReaderFileReader and and FileWriterFileWriter—allow you to treat a file as a stream to input —allow you to treat a file as a stream to input or output sequentiallyor output sequentially• Each file stream type has three types of constructorsEach file stream type has three types of constructors

A constructor that takes a A constructor that takes a StringString which is the name of the file which is the name of the file A constructor that take a A constructor that take a FileFile object which refers to the file object which refers to the file A constructor that takes a A constructor that takes a FileDescriptorFileDescriptor object object

Random-Access file: Random-Access file: RandomAccessFileRandomAccessFile allow you to allow you to read/write data beginning at the a specified locationread/write data beginning at the a specified location• a a file pointerfile pointer is used to guide the starting position is used to guide the starting position• It’s not a subclass of It’s not a subclass of InputStreamInputStream, , OutputStreamOutputStream, , ReaderReader or or

WriterWriter because it supports both input and output with both because it supports both input and output with both bytes and charactersbytes and characters

Example of RandomAccessFileExample of RandomAccessFile

import java.io.*;import java.io.*;class Filecopy {class Filecopy { public static void main(String args[]) {public static void main(String args[]) { RandomAccessFile fh1 = null;RandomAccessFile fh1 = null; RandomAccessFile fh2 = null;RandomAccessFile fh2 = null; long filesize = -1;long filesize = -1; byte[] buffer1;byte[] buffer1;

try {try { fh1 = new RandomAccessFile(args[0], “r”);fh1 = new RandomAccessFile(args[0], “r”); fh2 = new RandomAccessFile(args[1], “rw”);fh2 = new RandomAccessFile(args[1], “rw”); } catch (FileNotFoundException e) {} catch (FileNotFoundException e) { System.out.println(“File not found”);System.out.println(“File not found”); System.exit(100);System.exit(100); }}

try {try { filesize = filesize = fh1.length();fh1.length(); int bufsize = (int)filesize/2;int bufsize = (int)filesize/2; buffer1 = new byte[bufsize];buffer1 = new byte[bufsize]; fh1.readFully(buffer1, 0, bufsize);fh1.readFully(buffer1, 0, bufsize); fh2.write(buffer1, 0, bufsize);fh2.write(buffer1, 0, bufsize); } catch (IOException e) {} catch (IOException e) { System.out.println("IO error occurred!");System.out.println("IO error occurred!"); System.exit(200);System.exit(200); }} }}}}

Add more efficiencyAdd more efficiency

BufferedReaderBufferedReader reads text from a character-input stream, reads text from a character-input stream, buffering characters so as to provide for the efficient buffering characters so as to provide for the efficient reading of characters, arrays, and lines. reading of characters, arrays, and lines.

BufferedReader (Reader in)BufferedReader (Reader in)

For example:For example:

to wrap an to wrap an InputStreamReaderInputStreamReader inside a inside a BufferedReaderBufferedReader

BufferedReader in BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); = new BufferedReader(new InputStreamReader(System.in));

to wrap a to wrap a FileReaderFileReader inside a inside a BufferedReaderBufferedReader

BufferedReader in BufferedReader in = new BufferedReader(new FileReader(“fileName”)); = new BufferedReader(new FileReader(“fileName”));

then you can invoke then you can invoke in.readLine()in.readLine() to read from the file to read from the file line by lineline by line

import java.io.*;import java.io.*;public class EfficientReader {public class EfficientReader { public static void main (String[] args) {public static void main (String[] args) {

try {try { BufferedReader br = new BufferedReader(new FileReader(args[0]));BufferedReader br = new BufferedReader(new FileReader(args[0]));

// get line// get line String line = String line = br.readLinebr.readLine();();

// while not end of file… keep reading and displaying lines// while not end of file… keep reading and displaying lines while (line != null) {while (line != null) { System.out.println("Read a line:"); System.out.println("Read a line:"); System.out.println(line); System.out.println(line); line = line = br.readLinbr.readLine();e(); }} // close stream// close stream br.closebr.close();(); } catch(FileNotFoundException fe) {} catch(FileNotFoundException fe) { System.out.println("File not found: “+ args[0]");System.out.println("File not found: “+ args[0]"); } catch(IOException ioe) {} catch(IOException ioe) { System.out.println("Can’t read from file: “+args[0]);System.out.println("Can’t read from file: “+args[0]); }} }}}}

BufferingBuffering Improves performance of I/O Improves performance of I/O Copies each output to a region of memory called a buffer Copies each output to a region of memory called a buffer Entire buffer output to disk at once Entire buffer output to disk at once One long disk access takes less time than many smaller ones One long disk access takes less time than many smaller ones

• BufferedInputStreamBufferedInputStream buffers file output buffers file output • BufferedOutputStreamBufferedOutputStream buffers file input buffers file input

Appending to a FileAppending to a File To append to file instead of overwriting it pass the boolean To append to file instead of overwriting it pass the boolean

value true as the second argument to the FileOutputStream() value true as the second argument to the FileOutputStream() constructor. For example, constructor. For example,

FileOutputStream fos = new FileOutputStream(“File.txt", true); FileOutputStream fos = new FileOutputStream(“File.txt", true);

More on Writing to a FileMore on Writing to a File The java.io.FileWriter class writes text files using the The java.io.FileWriter class writes text files using the

platform's default character encoding and the buffer size. If platform's default character encoding and the buffer size. If you need to change these values, construct an you need to change these values, construct an OutputStreamReader on a FileOutputStream instead. OutputStreamReader on a FileOutputStream instead.

LineNumberReader classLineNumberReader class The java.io.LineNumberReader class is a subclass of The java.io.LineNumberReader class is a subclass of

java.io.BufferedReader that keeps track of which line java.io.BufferedReader that keeps track of which line you're currently reading. It has all the methods of you're currently reading. It has all the methods of BufferedReader including readLine(). It also has two BufferedReader including readLine(). It also has two constructors, getLineNumber(), and setLineNumber() constructors, getLineNumber(), and setLineNumber() methods: methods:

• public LineNumberReader(Reader in) public LineNumberReader(Reader in) • public LineNumberReader(Reader in, int size) public LineNumberReader(Reader in, int size) • public int getLineNumber() public int getLineNumber() • public void setLineNumber(int lineNumber) public void setLineNumber(int lineNumber)

The setLineNumber() method does not change the file pointer. It just changes the value The setLineNumber() method does not change the file pointer. It just changes the value getLineNumber() returns. getLineNumber() returns.

For example, it would allow you to start counting from -5 if you knew there were six lines For example, it would allow you to start counting from -5 if you knew there were six lines of header data you didn't want to count. of header data you didn't want to count.

Lets look at some examplesLets look at some examples

First ---- using DataInputStream and First ---- using DataInputStream and DataOutputStreamDataOutputStream

Data Input/Output Stream exampleData Input/Output Stream exampleimport java.io.*;import java.io.*;

class DOSDISDemoclass DOSDISDemo

{{

public static void main (String [] args)public static void main (String [] args)

{{

DataOutputStream dos DataOutputStream dos = null;= null;

trytry

{{

FileOutputStream fos = new FileOutputStream ("data.dat");FileOutputStream fos = new FileOutputStream ("data.dat");

dos = new DataOutputStream (fos);dos = new DataOutputStream (fos);

dos.writeInt (256);dos.writeInt (256);

dos.writeDouble (Math.PI);dos.writeDouble (Math.PI);

dos.writeUTF ("Java");dos.writeUTF ("Java");

}}

catch (IOException e)catch (IOException e)

{ System.out.println (e.getMessage ());{ System.out.println (e.getMessage ());

return; }return; }

finallyfinally

{ if (dos != null){ if (dos != null)

trytry

{ dos.close (); }{ dos.close (); }

catch (IOException e) { }catch (IOException e) { }

}}

DataInputStream dis DataInputStream dis = null;= null;

trytry

{{

FileInputStream fis = new FileInputStream ("data.dat");FileInputStream fis = new FileInputStream ("data.dat");

dis = new DataInputStream (fis);dis = new DataInputStream (fis);

System.out.println (System.out.println (dis.readInt ());dis.readInt ());

System.out.println (System.out.println (dis.readDouble ());dis.readDouble ());

System.out.println (System.out.println (dis.readUTF ());dis.readUTF ());

}}

catch (IOException e)catch (IOException e)

{{

System.out.println (e.getMessage ());System.out.println (e.getMessage ());

return;return;

}}

finallyfinally

{{

if (dis != null)if (dis != null)

trytry

{ dis.close (); }{ dis.close (); }

catch (IOException e) { }catch (IOException e) { }

} }

}}

}}

OUTPUT256 3.141592653589793 Java

Another Example--- Piped Another Example--- Piped StreamsStreams

A Motivation?

•Threads are often required to communicate.•Can use piped streams.•IDEA= connect a piped output stream to a piped input stream. •Then, one thread writes data to the piped output stream and another thread reads that data by way of the piped input stream. •CAUTION= streams have limited sizes. As a result, a writing thread could write more output to a piped output stream than that stream can accommodate, and the excess output would be lost. To prevent that from happening, the reading thread must be responsive.

Buffered Streams, Piped Streams (here with Buffered Streams, Piped Streams (here with same thread)same thread)

import java.io.*;import java.io.*;public class BufferedReaderTest {public class BufferedReaderTest { public static void main(String[] args) public static void main(String[] args) throws IOExceptionthrows IOException {{ BufferedReader charStream = BufferedReader charStream = new BufferedReader (new new BufferedReader (new

InputStreamReaderInputStreamReader(System.in));(System.in)); String data = charStream.readLine(); // Read String data = charStream.readLine(); // Read

a line from standard inputa line from standard input

System.out.println("Input = " + data);System.out.println("Input = " + data); }}}}

The Buffered stream classes buffer their data The Buffered stream classes buffer their data to avoid every read or write going directly to to avoid every read or write going directly to the next stream. These classes are often used the next stream. These classes are often used in conjunction with File streams.in conjunction with File streams.

import java.io.*;import java.io.*;

class TextGenerator extends Thread {class TextGenerator extends Thread { private Writer out;private Writer out; public TextGenerator(Writer out) {public TextGenerator(Writer out) { this.out = out;this.out = out; }}

public void run() {public void run() { try {try { try {try { for (char c = 'a'; c <= 'z'; c++)for (char c = 'a'; c <= 'z'; c++) out.write(c);out.write(c); } finally {} finally { out.close();out.close(); }} } catch(IOException e) {} catch(IOException e) {

getUncaughtExceptionHandler().uncaughtExceptigetUncaughtExceptionHandler().uncaughtException(this, e);on(this, e);

}} }}}}public class Pipe {public class Pipe { public static void main(String[] args) public static void main(String[] args) throws IOExceptionthrows IOException {{ PipedWriter out = new PipedWriter();PipedWriter out = new PipedWriter(); PipedReader in = new PipedReader(out);PipedReader in = new PipedReader(out); TextGenerator data = new TextGenerator(out);TextGenerator data = new TextGenerator(out); data.start();data.start(); int ch;int ch; while ((ch=in.read()) != -1)while ((ch=in.read()) != -1) System.out.print((char) ch);System.out.print((char) ch); System.out.println();System.out.println(); }}}}

Result:abcdefghijklmnopqrstuvwxyz

InputStream Ch

ara

cte

r S

tream

Another Example--- Another Example--- LineNumberReaderLineNumberReader

Tracks Line numbers as you are Tracks Line numbers as you are readingreading

Print Streams, LineNumberReaderPrint Streams, LineNumberReader The Print streams provide The Print streams provide

methods that make it easy to methods that make it easy to write the values of primitive types write the values of primitive types and object to a stream, in a and object to a stream, in a human-readable text formathuman-readable text format• print and println methodprint and println method

The call out.print(f) is equivalent The call out.print(f) is equivalent to to out.write(String.valueOf(f).getBytout.write(String.valueOf(f).getBytes());es());

LineNumberReaderLineNumberReader The LineNumberReader stream The LineNumberReader stream

keeps track of line numbers while keeps track of line numbers while reading text. reading text.

import java.io.*;import java.io.*;

public class FindChar {public class FindChar { public static void main(String[] args) public static void main(String[] args) throws IOExceptionthrows IOException {{ if (args.length != 2)if (args.length != 2) throw new IllegalArgumentException(throw new IllegalArgumentException( "need char and file");"need char and file");

int match = args[0].charAt(0);int match = args[0].charAt(0); FileReader fileIn = new FileReader(args[1]);FileReader fileIn = new FileReader(args[1]); LineNumberReader in = new LineNumberReader in = new

LineNumberReader(fileIn);LineNumberReader(fileIn); int ch;int ch; while ((ch = in.read()) != -1) {while ((ch = in.read()) != -1) { if (ch == match) {if (ch == match) { System.out.println("'" + (char) ch +System.out.println("'" + (char) ch + "' at line " + "' at line " + in.getLineNumber());in.getLineNumber()); return ;return ; }} }} System.out.println((char) match + " not System.out.println((char) match + " not

found");found"); }}}}

Run:%java FindChar I FindChar.javaResult:‘I’ at line 4

Another Example …Pushback Another Example …Pushback StreamsStreams

Pushback is used on an input stream Pushback is used on an input stream to allow a byte to be read and then to allow a byte to be read and then returned(that is "pushed back") to returned(that is "pushed back") to the stream.the stream.

PushbackInputStream provides a PushbackInputStream provides a mechanism to "mechanism to "peekpeek " at what is " at what is coming from an input stream without coming from an input stream without disrupting it.disrupting it.

Pushback StreamsPushback Streams A Pushback stream lets you push A Pushback stream lets you push

back, or “unread” characters or back, or “unread” characters or bytes when you have read too bytes when you have read too far. Pushback is typically useful far. Pushback is typically useful for breaking input into tokens. for breaking input into tokens.

For example, lexical scanners For example, lexical scanners often know that a token (such as often know that a token (such as an identifier) has ended only an identifier) has ended only when they have read the first when they have read the first character that follows it.character that follows it.

The following example uses The following example uses PushbackInputStream to report PushbackInputStream to report the longest consecutive sequence the longest consecutive sequence of any single byte in its input: of any single byte in its input:

import java.io.*;import java.io.*;

public class SequenceCount {public class SequenceCount { public static void main(String[] args) public static void main(String[] args) throws IOExceptionthrows IOException {{

PushbackInputStreamPushbackInputStream in = new PushbackInputStream(System.in);in = new PushbackInputStream(System.in); int max = 0; // longest sequence found int max = 0; // longest sequence found int maxB = -1; // the byte in that sequenceint maxB = -1; // the byte in that sequence int b; // current byte in inputint b; // current byte in input

do {do { int cnt;int cnt; int b1 = in.read();int b1 = in.read(); for (cnt = 1; (b = in.read()) == b1; cnt++)for (cnt = 1; (b = in.read()) == b1; cnt++) continue;continue; if (cnt > max) {if (cnt > max) { max = cnt; // remember lengthmax = cnt; // remember length maxB = b1; // remember which byte valuemaxB = b1; // remember which byte value }} in.unread(b); in.unread(b); // pushback start of ntext seq// pushback start of ntext seq } while (b != -1); // until we hit end of input} while (b != -1); // until we hit end of input System.out.println(max + " byte of " + maxB);System.out.println(max + " byte of " + maxB); }}}}

Run and Result:% java SequenceCount12345111^D in Unix(or ^Z in Windows)3 bytes of 49

Another ExampleAnother Example

Java I/O even has ability to read zip Java I/O even has ability to read zip filesfiles

java.util.zipjava.util.zip• ZipInputStream ,ZipOutputStreamZipInputStream ,ZipOutputStream

Zip File Example –will list contentsZip File Example –will list contents// ZipReader.java// ZipReader.java

import java.io.*;import java.io.*;

import java.util.zip.*;import java.util.zip.*;

class ZipReaderclass ZipReader

{{

public static void main (String [] args)public static void main (String [] args)

{{

if (args.length != 1)if (args.length != 1)

{{

System.out.println ("usage: java ZipReader pathname");System.out.println ("usage: java ZipReader pathname");

return;return;

}}

ZipInputStreamZipInputStream zis = null; zis = null;

trytry

{{

FileInputStream fis = new FileInputStream (args [0]);FileInputStream fis = new FileInputStream (args [0]);

zis = new ZipInputStream (fis);zis = new ZipInputStream (fis);

ZipEntry ze;ZipEntry ze;

while ((while ((ze = zis.getNextEntry ze = zis.getNextEntry ()) != null)()) != null)

System.out.println (System.out.println (ze.getName ());ze.getName ());

}}

// ZipReader.java// ZipReader.java

catch (IOException e)catch (IOException e)

{{

System.out.println (e.getMessage ());System.out.println (e.getMessage ());

}}

finallyfinally

{{

trytry

{{

zis.close ();zis.close ();

}}

catch (IOException e)catch (IOException e)

{{

}}

}}

}}

}}

To run ZipReader, To run ZipReader, you need access to you need access to either a Zip file or a either a Zip file or a Jar file (which is Jar file (which is basically a Zip file basically a Zip file with a .jar extensionwith a .jar extension

A useful class in I/O –the A useful class in I/O –the StreamTokenizerStreamTokenizer

The StreamTokenizer gives simple The StreamTokenizer gives simple tokenization. tokenization.

More general facility for scanning More general facility for scanning and converting input text is provided and converting input text is provided by the jby the java.util.Scannerava.util.Scanner class. class.

StreamTokenzierStreamTokenzier Four token typeFour token type

• TT_WORDTT_WORD• TT_NUMBERTT_NUMBER• TT_EOLTT_EOL• TT_EOFTT_EOF

import java.io.*;import java.io.*;class StreamTokenizerDemo {class StreamTokenizerDemo { public static void main(String args[]) {public static void main(String args[]) { try {try { FileReader fr = new FileReader(args[0]);FileReader fr = new FileReader(args[0]); BufferedReader br = new BufferedReader(fr);BufferedReader br = new BufferedReader(fr); StreamTokenizer st = new StreamTokenizer(br);StreamTokenizer st = new StreamTokenizer(br); st.ordinaryChar('.');st.ordinaryChar('.'); st.wordChars('\'', '\'');st.wordChars('\'', '\''); while(st.nextToken() != StreamTokenizer.TT_EOF) {while(st.nextToken() != StreamTokenizer.TT_EOF) { switch(st.ttype) {switch(st.ttype) { case StreamTokenizer.TT_WORD:case StreamTokenizer.TT_WORD: System.out.println(st.lineno() + ") " + System.out.println(st.lineno() + ") " + st.sval);st.sval); break;break; case StreamTokenizer.TT_NUMBER:case StreamTokenizer.TT_NUMBER: System.out.println(st.lineno() + ") " + System.out.println(st.lineno() + ") " + st.nval);st.nval); break;break; default:default: System.out.println(st.lineno() + ") " + System.out.println(st.lineno() + ") " + (char)st.ttype);(char)st.ttype); } }} } fr.close();fr.close(); }} catch (Exception e) {catch (Exception e) { System.out.println("Exception: " + e);System.out.println("Exception: " + e); }} }}}}

Input (tokens.txt)The price is $23.45.Is that too expensive?(I don’t think so.)

Run: java StreamTokenizerDemo tokens.txt

Result1) The1) price1) is1) $1) 23.451) .2) Is2) that2) too2) expensive2) ?3) (3) I3) don’t3) think3) so3) .3) )

Another on ….Data Byte StreamsAnother on ….Data Byte Streams DataInput and DataOutput DataInput and DataOutput These interfaces define These interfaces define

methods that transmit methods that transmit primitive types across a primitive types across a stream.stream.

Read / Write methodsRead / Write methods

Read Write TypeRead Write TypereadBoolean writeBoolean booleanreadBoolean writeBoolean booleanreadChar writeChar charreadChar writeChar charreadByte writeByte bytereadByte writeByte bytereadShort writeShort shortreadShort writeShort shortreadInt writeInt intreadInt writeInt intreadLong writeLong longreadLong writeLong longreadFloat writeFloat floatreadFloat writeFloat floatreadDouble writeDouble doublereadDouble writeDouble doublereadUTF writeUTF String(in UTF format)readUTF writeUTF String(in UTF format)

public static void writeData(double[] data, public static void writeData(double[] data, String file)String file)

throws IOExceptionthrows IOException{{ OutputStream fout = new OutputStream fout = new

FileOutputStream(file);FileOutputStream(file); DataOutputStream out = new DataOutputStream out = new

DataOutputStream(fout);DataOutputStream(fout); out.writeInt(data.length)out.writeInt(data.length) for(double d : data) out.writeDouble(d);for(double d : data) out.writeDouble(d); out.close();out.close();}}

public static double[] readData(String file)public static double[] readData(String file) throws IOExceptionthrows IOException{{ InputStream fin = new FileInputStream(file);InputStream fin = new FileInputStream(file); DataInputStream in = new DataInputStream in = new

DataInputStream(fin);DataInputStream(fin); double[] data = new double[in.readInt()];double[] data = new double[in.readInt()]; for (int i = 0; i < data.length; i++)for (int i = 0; i < data.length; i++) data[i] = indata[i] = in.readDouble.readDouble();(); in.close();in.close(); return data;return data;}}

Reading and Writing Objects?Reading and Writing Objects?

What if we could save and store and What if we could save and store and object and read it (bring it back to object and read it (bring it back to life)….wow!life)….wow!

Object SerializationObject Serialization What is Object Serialization?What is Object Serialization?

• SerializationSerialization: process of converting an object’s representation : process of converting an object’s representation into a stream of bytesinto a stream of bytes

• DeserializationDeserialization: reconstituting an object from a byte stream: reconstituting an object from a byte stream

• Process of reading and writing objects Process of reading and writing objects

• Writing an object is to represent its state in a serialized form Writing an object is to represent its state in a serialized form sufficient to reconstruct the object as it is read. sufficient to reconstruct the object as it is read.

• serializationserialization is the process of converting a object state into a is the process of converting a object state into a format that can be stored (for example, in a file or memory format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and buffer, or transmitted across a network connection link) and "resurrected" later in the same or another computer "resurrected" later in the same or another computer environment.environment.

Serializing ObjectsSerializing Objects

How to Write to an How to Write to an ObjectOutputStreamObjectOutputStream• Writing objects to a stream Writing objects to a stream

is a straight-forward is a straight-forward process. Example of process. Example of constructing a Date object constructing a Date object and then serializing that and then serializing that object:object:

FileOutputStream out = new FileOutputStream out = new FileOutputStream("theTime");FileOutputStream("theTime");

ObjectOutputStream s = new ObjectOutputStream s = new ObjectOutputStream(out);ObjectOutputStream(out);

s.writeObject("Today");s.writeObject("Today");

s.writeObject(new Date());s.writeObject(new Date());

s.flush(); s.flush();

How to Read from an How to Read from an ObjectOutputStreamObjectOutputStream• Example that reads in the Example that reads in the

String and the Date object String and the Date object that was written to the file that was written to the file named theTime in the read named theTime in the read example: example:

FileInputStream in = new FileInputStream in = new FileInputStream("theTime"); FileInputStream("theTime");

ObjectInputStream s = new ObjectInputStream s = new ObjectInputStream(in); ObjectInputStream(in);

String today = String today = (String)s.readObject(); (String)s.readObject();

Date date = Date date = (Date)s.readObject();(Date)s.readObject();

Serializing ObjectsSerializing Objects

Providing Object Serialization for Your Classes Providing Object Serialization for Your Classes

• Implementing the Serializable InterfaceImplementing the Serializable Interface• Customizing SerializationCustomizing Serialization• Implementing the Externalizable InterfaceImplementing the Externalizable Interface• Protecting Sensitive InformationProtecting Sensitive Information

Files ---and Channels+Files ---and Channels+

Accessing FilesAccessing Files ChannelsChannels

• Channels were introduced in the 1.4 release of Java to provide a faster Channels were introduced in the 1.4 release of Java to provide a faster capability for a capability for a faster capability for input and output operations faster capability for input and output operations with with files, network sockets, and piped I/O operations between programs files, network sockets, and piped I/O operations between programs than the methods provided by the stream classes.than the methods provided by the stream classes.

• The channel mechanism can take advantage of The channel mechanism can take advantage of bufferingbuffering and other and other capabilities of the underlying operating system and therefore is capabilities of the underlying operating system and therefore is considerably more efficient than using the operations provided directly considerably more efficient than using the operations provided directly within the file stream classes.within the file stream classes.

A summary of the essential role of each of them in file operationsA summary of the essential role of each of them in file operations• A File object encapsulates a path to a file or a directory, and such an A File object encapsulates a path to a file or a directory, and such an

object encapsulating a file path can be used to construct a file stream object encapsulating a file path can be used to construct a file stream object.object.

• A FileInputStream object encapsulates a file that can be read by a A FileInputStream object encapsulates a file that can be read by a channel. A FileoutputStream object encapsulates a file that can be channel. A FileoutputStream object encapsulates a file that can be written by a channel.written by a channel.

• A buffer just holds data in memory. The loaded data to be written to a A buffer just holds data in memory. The loaded data to be written to a file will be saved at buffer using the buffer’s put() method, and file will be saved at buffer using the buffer’s put() method, and retrieved using buffer’s get() methods.retrieved using buffer’s get() methods.

• A A FileChannelFileChannel object can be obtained from a file stream object or a object can be obtained from a file stream object or a RandomAccessFile object.RandomAccessFile object.

Accessing FilesAccessing Files

The hierarchy of the channel interfaces

Accessing FilesAccessing Files

The Capacities of Different Buffers

Channel Example (ReadPrimes)Channel Example (ReadPrimes)import java.io.File;import java.io.File;import java.io.FileInputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.IOException;import java.io.FileNotFoundException;import java.io.FileNotFoundException;import java.nio.ByteBuffer;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.FileChannel;

public class ReadPrimes {public class ReadPrimes { public static void main(String[] args) {public static void main(String[] args) { File aFile = new File("primes.bin");File aFile = new File("primes.bin"); FileInputStream inFile = null;FileInputStream inFile = null; try {try { inFile = new FileInputStream(aFile); inFile = new FileInputStream(aFile);

} catch(FileNotFoundException e) {} catch(FileNotFoundException e) { e.printStackTrace(System.err);e.printStackTrace(System.err); System.exit(1);System.exit(1); }} FileChannel inChannel = FileChannel inChannel =

inFile.getChannel(); inFile.getChannel(); final int PRIMECOUNT = 6;final int PRIMECOUNT = 6; ByteBuffer buf = ByteBuffer buf =

ByteBuffer.allocate(8*PRIMECOUNT); ByteBuffer.allocate(8*PRIMECOUNT); long[] primes = new long[PRIMECOUNT];long[] primes = new long[PRIMECOUNT];

try {try { while(inChannel.read(buf) != -1) {while(inChannel.read(buf) != -1) { ((ByteBuffer)((ByteBuffer)

(buf.flip())).asLongBuffer().get(primes);(buf.flip())).asLongBuffer().get(primes);

// List the primes read on the same line// List the primes read on the same line System.out.println();System.out.println(); for(long prime : primes)for(long prime : primes) System.out.printf("%10d", prime);System.out.printf("%10d", prime); buf.clear(); // Clear the buffer buf.clear(); // Clear the buffer

for the next readfor the next read }} System.out.println("\nEOF reached.");System.out.println("\nEOF reached."); inFile.close(); // Close the file inFile.close(); // Close the file

and the channeland the channel } catch(IOException e) {} catch(IOException e) { e.printStackTrace(System.err);e.printStackTrace(System.err); System.exit(1);System.exit(1); }} System.exit(0);System.exit(0); }}}} You also need to read the

“PrimesToFile.java” which prints prime numbers to the file.

Channel Setup

Buffer Setup

From the channel, read data and save to the buffer