| CS 535: Object-Oriented Programming & Design |
|
---|
Fall Semester, 1997
Doc 17, Java IO
To Lecture Notes Index
San Diego State University -- This page last updated 21-Oct-97
Contents of Doc 17, Java IO
- References
- The I/O Package
- Reader
- Writer
- PrintWriter
- PrintStream
- Easy Input - UnicodeReader
- Creating New Streams
- Converting between Char and Byte based Streams
- Compressed Streams
- Stream Streams
- OutputStream
- FileInputStream
- FileOutputStream
- ASCIIInputStream
- Combining InputStreams
- Combining OutputStreams
The Java Programming Language, Arnold and Gosling, Chapter 11
On-line Java Documentation
Java source code
From a programmer's point of view, the user is a peripheral that types when
you issue a read request
- Peter Williams
Java I/O is defined in terms of streams
Streams are ordered sequences of data that have:
- A source (input streams) or
-
-
- A destination (output stream)
Streams as "Pipes"
- InputStream
-
-
- OutputStream
-
Streams are designed to be combined
-
The Four Fold Way
Byte based streams
- Streams uses to read/write raw bytes
-
- Initially used to read/write text
-
- Do not handle Unicode well
-
- java.io classes ending in Stream
Character based streams
- Use for all text IO
-
- Handles Unicode and local encodings properly
-
- More efficient than byte based streams
-
- java.io classes ending in Reader or Writer
Input Streams
- Used for input - reading
-
- Byte based input stream classes end in InputStream
-
- Character based input stream classes end in Reader
Output Streams
- Used for output - writing
-
- Byte based input stream classes end in OutputStream
-
- Character based input stream classes end in Writer
Readers (Writers) verses InputStreams (OutputStream)
Reader-Writers use chars, which are 16 bit
Reader-Writers are newer and tend to replace the use of
InputStreams-OutputStreams
InputStreams-OutputStreams use bytes, which are 8 bit
The Fourfold Way
For each Reader subclass there tends to be a corresponding InputStream
subclass
BufferedReader BufferedInputStream
FileReader FileInputStream
For each Writer subclass there tends to be a corresponding OutputStream
subclass
BufferedWriter BufferedOutputStream
FileWriter FileOutputStream
For each Writer subclass there tends to be a corresponding Reader subclass
Stream Types
Each type of stream results in four actual streams:
- Byte based input
- Byte based output
- Character based input (Reader)
- Character based output (Writer)
Piped Streams
- Useful in communications between threads
ByteArray Streams
- Read/write byte arrays
Filter Streams
- Abstract classes, filter bytes from another stream
- Can be chained together
Buffered Streams
- Adds buffering
Data Streams
- Reads/writes built-in types (int, float, etc. )
- Steam stores types in binary not ASCII or Unicode
File Streams
- Used for file IO
An abstract class representing an input stream of characters. All Readers are
based on this class.
Methods
close() | read(char[], int, int) |
mark(int) | ready() |
markSupported() | reset() |
read() | skip(long) |
read( char[] ) | |
Description of Methods for Reader
close()
- Close the stream.
mark(int)
- Mark the present position in the stream.
markSupported()
- Tell whether this stream supports the mark() operation.
read()
- Read a single character.
read(char[])
- Read characters into an array.
read(char[], int, int)
- Read characters into a portion of an array.
ready()
- Tell whether this stream is ready to be read.
reset()
- Repositions the stream to the last marked position.
skip(long)
- Skip n characters.
Reader Example
class CountSize
{
public static void main( String args[] ) throws IOException,
FileNotFoundException
{
try
{
Reader in = new FileReader( "Exam" );
int total;
for ( total = 0; in.read() != -1; total++)
;
System.out.println( total );
}
catch ( FileNotFoundException fileProblem )
{
System.err.println( "File not found" );
throw fileProblem;
}
catch ( IOException ioProblem )
{
System.err.println( "IO problem" );
throw ioProblem;
}
}
}
Output
7428
Read, int and Char
read() returns -1 if end of stream is reached, else returns the next byte
class Read
{
public static void main( String args[] ) throws IOException
{
Reader in = new StringReader( "abcdefghij" );
System.out.println( in.read() + " raw read, ascii value " );
System.out.println( (char) in.read() + " cast read to char " );
}
}
Output
97 raw read, ascii value
b cast read to char
Abstract class representing an output stream of chars. All Writers are based on
this class.
Methods
close() | write(char[], int, int) |
flush() | write(int) |
write(char[]) | write(String) |
write(String, int, int) |
Description of Methods
close()
- Closes the stream
flush()
- Flushes the stream
write(char[])
- Writes an array of chars
write(chars[], int, int)
- Writes a sub array of chars
write(int)
- Writes a single character
write(String)
- Write a string
FileWriter Example
class Capitalize
{
public static void main( String args[] ) throws IOException
{
Reader in = new StringReader( "abcdefghij" );
Writer out = new FileWriter( "Example");
int nextChar;
while ( ( nextChar = in.read() ) != -1 )
out.write( Character.toUpperCase( (char) nextChar ) );
out.write( '\n' );
out.flush(); // not needed before a close
out.close(); // exiting program closes the Writer
}
}
Output
ABCDEFGHIJ
Contains higher level output methods
Constructors
PrintWriter(Writer)
- Creates a new PrintWriter.
PrintWriter(Writer, boolean)
- Creates a new PrintWriter, with auto flushing.
Some PrintWriter Methods
checkError() | print(int) | println(double) |
close() | print(long) | println(float) |
flush() | print(Object) | println(int) |
print(boolean) | print(String) | println(long) |
print(char) | println() | println(Object) |
print(char[]) | println(boolean) | println(String) |
print(double) | println(char) | setError() |
print(float) | println(char[]) | write(int) |
checkError()
- Flushes the print writer and returns whether or not there was an error on
the writer.
PrintWriter Example
class EasyPrint
{
public static void main( String args[] ) throws IOException
{
Writer out = new FileWriter( "LetterHome");
PrintWriter easyOut = new PrintWriter( out );
easyOut.println( "Hi Mom" );
easyOut.println( 5 );
easyOut.println( true );
easyOut.close();
}
}
Output File
Hi Mom
5
true
In Slow Motion
Writer out = new FileWriter( "LetterHome");
PrintWriter easyOut = new PrintWriter( out );
Buffering IO
Buffer any IO operations that might be expensive
class BufferExample
{
public static void main( String args[] ) throws IOException
{
Writer out = new FileWriter( "LetterHome");
BufferedWriter buffered = new BufferedWriter( out);
PrintWriter easyOut = new PrintWriter( buffered );
easyOut.println( "Hi Mom and Dad" );
easyOut.println( "Please send " );
easyOut.println( 5.03 );
easyOut.println( "dollars");
easyOut.println( true );
easyOut.close();
}
}
In Slow Motion
Writer out = new FileWriter( "LetterHome");
BufferedWriter buffered = new BufferedWriter( out);
PrintWriter easyOut = new PrintWriter( buffered );
Shorthand Notation
class Test
{
public static void main( String args[] ) throws IOException
{
PrintWriter easyOut = new PrintWriter(
new BufferedWriter(
new FileWriter( "Example")
)
);
easyOut.println( " Hi Mom" );
easyOut.println( 5 );
easyOut.println( true );
easyOut.close();
}
}
Used for "ascii" output
System.out is a PrintStream
PrintWriter is preferred over PrintStream
class PrintStreamExample
{
public static void main( String args[] )
{
System.out.println( "Hi Mom" );
}
}
Constructors
Constructors are deprecated, to discourage use of PrintStream. Use
PrintWriter!
PrintStream Methods
checkError() | print(int) | println(double) |
close() | print(long) | println(float) |
flush() | print(Object) | println(int) |
print(boolean) | print(String) | println(long) |
print(char) | println() | println(Object) |
print(char[]) | println(boolean) | println(String) |
print(double) | println(char) | write(byte[], int, int) |
print(float) | println(char[]) | write(int) |
checkError()
- Flushes the print stream and returns whether or not there was an error on
the output stream.
PrintStream, '\n' and auto flush
If auto flushing is on (default) then printing a '\n' flushes the buffer in a
PrintStream
What is a newline?
Different platforms (Unix, PC, Mac) use different characters to represent a
newline.
PrintStream, PrintWriter use platform specific newline
BufferedWriter has a newLine() method which uses platform specific newline
Finding out what the newline is
The System properties contain user and platform information
System.getProperties() returns all the properties
System.getProperty( "property Name") returns the value of the given
property
class Test
{
public static void main( String args[] ) throws IOException
{
System.out.println( System.getProperties() );
}
}
Output (Formatted Afterwards)
file.encoding | 8859_1 |
file.encoding.pkg | sun.io |
file.separator | / |
java.class.path | |
java.class.version | 45.3 |
java.home | /opt/java/bin/.. |
java.vendor | Sun Microsystems Inc. |
java.vendor.url | http://www.sun.com/ |
java.vendor.url.bug | http://java.sun.com/cgi-bin/bugreport.cgi |
java.version | 1.1.4 |
line.separator | \n |
os.arch | sparc |
os.name | Solaris |
os.version | 2.x |
path.separator | : |
user.dir | /net/www/www-eli/java/cs535 |
user.home | /net/www/www-eli |
user.language | en |
user.name | whitney |
user.timezone | PST |
Description of System Properties
This set of system properties always includes values for the following keys:
Key | Description of Associated Value |
java.version | Java version number |
java.vendor | Java vendor-specific string |
java.vendor.url | Java vendor URL |
java.home | Java installation directory |
java.class.version | Java class format version number |
java.class.path | Java class path |
os.name | Operating system name |
os.arch | Operating system architecture |
os.version | Operating system version |
file.encoding.pkg | Package that contains converters between local encodings and Unicode |
file.encoding | Character encoding for default locale |
file.separator | File separator ("/" on UNIX) |
path.separator | Path separator (":" on UNIX) |
line.separator | Line separator ("\n" on UNIX) |
user.name | User's account name |
user.home | User's home directory |
user.dir | User's current working directory |
user.language | 2-letter code of default locale |
user.timezone | default time zone |
The toString() Standard
class PoorPrint
{
String name = "sam";
}
class FancyPrint
{
String name = "pete";
public String toString()
{
return "FancyPrint( " + name + " )";
}
}
class TestPrint
{
public static void main( String args[] )
{
PoorPrint outOfIt = new PoorPrint();
FancyPrint cool = new FancyPrint();
System.out.println( outOfIt );
System.out.println( cool );
}
}
Output
PoorPrint@5e300848
FancyPrint( pete )
The toString() StandardHow Does it Work?
Print in PrintStream
public void print( Object obj )
{
write( String.valueOf( obj ) );
}
String.valueOf
public static String valueOf(Object obj)
{
return (obj == null) ? "null" : obj.toString();
}
Object.toString()
public String toString()
{
return getClass().getName() + "@" +
Integer.toHexString(hashCode());
}
Constructors
UnicodeReader (Reader)
- Creates a new UnicodeReader.
Unicode Method
eof() | readDouble() | readLong() |
flushLine() | readFloat() | readShort() |
read(char[]) | readFully(char[]) | readUnsignedByte() |
read(char[], int, int) | readFully(char[], int, int) | readUnsignedShort() |
readBoolean() | readInt() | readWord() |
readChar() | readLine() | skipChars(int) |
Using UnicodeReader
import java.io.*;
import sdsu.io.*;
class ReadingFileExample
{
public static void main( String args[] ) throws Exception
{
FileReader inputFile;
BufferedReader bufferedFile;
UnicodeReader cin;
inputFile = new FileReader( "ReadingFileExample.java" );
bufferedFile = new BufferedReader( inputFile );
cin = new UnicodeReader( bufferedFile );
System.out.println( cin.readWord() );
for ( int k = 1 ; k < 4; k++ )
System.out.println( cin.readLine() );
}
}
Output
import
sdsu.io.*;
import java.io.*;
class ReadingFileExample
UnicodeReader, DataOutputStream, DataInputStream
DataInputStream appears to have the same type of input as UnicodeReader and
ASCIIInputStream
All three can return primitive types: boolean, int, etc.
DataInputStream requires that boolean, int, etc. are in binary format, what is
written by DataOutputStream
UnicodeReader and ASCIIInputStream read string representations of int, float,
etc. and convert them to int, float, etc.
UpperCaseReader Example
public static void main( String args[] ) throws Exception
{
Reader input = new StringReader( "hi mom how is dad?" );
// UpperCaseReader is define on next slide
input = new UpperCaseReader( input );
UnicodeReader cin = new UnicodeReader( input );
System.out.println( cin.readWord() );
System.out.println( cin.readLine() );
}
Output
HI
MOM HOW IS DAD?
UpperCaseReader Example - Continued
class UpperCaseReader extends FilterReader {
public static final int EOF = -1;
public UpperCaseReader( Reader input ) {
super( input );
}
public int read() throws IOException {
int nextChar = super.read();
if ( nextChar == EOF )
return EOF;
else
return toUpperCase( (char) nextChar );
}
public int read(char chars[], int offset, int length) throws
IOException {
int charsRead = super.read(chars, offset, length);
if ( charsRead == EOF )
return EOF;
for ( int k = offset; k < offset + charsRead; k++)
chars[ k ] = toUpperCase( chars[ k ] ) ;
return charsRead;
}
private char toUpperCase( char convertMe ) {
return Character.toUpperCase( convertMe );
}
}
Useful StringWriter
The StringWriter writes to a string
All Writers than can be used to help create a string
class StringWriterExample
{
public static void main( String args[] ) throws Exception
{
StringWriter outputString = new StringWriter();
// see next slide for UpperCaseWriter
UpperCaseWriter upperCaseOutput =
new UpperCaseWriter( outputString);
PrintWriter cout = new PrintWriter( upperCaseOutput );
cout.println( "Hi Mom" );
cout.println( 3.14);
System.out.println( outputString.toString() );
}
}
Output
HI MOM
3.14
Example of a FilterWriter
class UpperCaseWriter extends FilterWriter {
public static final int EOF = -1;
public UpperCaseWriter( Writer output ) {
super( output ); // input is stored in field "out"
}
public void write(int c) throws IOException {
if ( c == EOF)
super.write( c );
else
super.write( Character.toUpperCase( (char) c ));
}
public void write(char cbuf[], int off, int len) throws IOException {
write( new String( cbuf), off, len);
}
public void write(String str, int off, int len) throws IOException {
if ( len <= 0 )
super.write( str, off, len);
else
super.write( str.toUpperCase(), off, len);
}
}
InputStreamReader
A bridge between byte based InputStreams and Readers
Reads bytes and converts them to unicode
Conversion does not have to be the obvious one, i.e.
- \064 -> \u0064
-
- You may want 'a' to map to the "a" in Cyrillic
Can specify different encodings to map bytes to unicode
By default uses the local encoding
Sample Use of InputStreamReader
import java.io.InputStreamReader;
import java.io.InputStream;
import sdsu.io.UnicodeReader;
class Test
{
public static void main( String args[] )
{
InputStream in = System.in;
InputStreamReader unicode = new InputStreamReader( in );
UnicodeReader easyIn = new UnicodeReader( unicode );
//Now you can use easyIn
}
}
OutputStreamWriter
A bridge between byte based OutputStreams and Writers
Converts unicode chars to bytes
Conversion does not have to be the obvious one
- \u0064 -> \064
Can specify different encodings
By default uses the local encoding
OutputStreamWriter Example
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.io.PrintWriter;
class Test
{
public static void main( String args[] )
{
OutputStream out = System.out;
OutputStreamWriter unicode =
new OutputStreamWriter( out );
PrintWriter easyOut = new PrintWriter( unicode );
//Now you can use easyOut
}
}
java.util.zip.GZIPOutputStream
- compressed output using gzip format
java.util.zip.GZIPInputStream
- decompressed gzip data
Sample Use of GZIP classes
import java.io.*;
import sdsu.io.ASCIIInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.GZIPInputStream;
class Compressed
{
public static void main( String args[] ) throws IOException
{
OutputStream outputFile =
new FileOutputStream( "Compressed" );
PrintWriter cout =
new PrintWriter (new GZIPOutputStream( outputFile ));
cout.println("Hi Mom");
cout.close();
// the file "Compressed" now contains compress version of
// the string "Hi Mom"
FileInputStream inputFile =
new FileInputStream( "Compressed" );
ASCIIInputStream cin =
new ASCIIInputStream (
new GZIPInputStream( inputFile ));
System.out.println( cin.readLine());
}
}
Abstract class representing an output stream of bytes. All OutputStreams are
based on this class.
Note byte oriented IO works on ascii only, not Unicode
Methods
close() | write(byte[], int, int) |
flush() | write(int) |
write(byte[]) | |
Description of Methods
close()
- Closes the stream
flush()
- Flushes the stream
write(byte[])
- Writes an array of bytes
write(byte[], int, int)
- Writes a sub array of bytes
write(int)
- Writes a byte
OutputStream Example
class CountSize
{
public static void main( String args[] ) throws IOException
{
InputStream in;
in = new StringBufferInputStream( "abcdefghij" );
OutputStream out = System.out;
int nextChar;
while ( ( nextChar = in.read() ) != -1 )
out.write( Character.toUpperCase( (char) nextChar ) );
out.write( '\n' );
out.flush();
}
}
Output
ABCDEFGHIJ
Constructors
FileInputStream(String)
- Creates an input file with the specified system dependent file name.
FileInputStream(File)
- Creates an input file from the specified File object.
FileInputStream(FileDescriptor)
FileInputStream Methods
available() | read() |
close() | read(byte[]) |
finalize() | read(byte[], int, int) |
getFD() | skip(long) |
Constructors
FileOutputStream(String)
- Creates an output file with the specified system dependent file name.
FileOutputStream(File)
- Creates an output file with the specified File object.
FileOutputStream(FileDescriptor)
FileOutputStream Methods
close() | write(byte[]) |
finalize() | write(byte[], int, int) |
getFD() | write(int) |
Constructors
ASCIIInputStream(InputStream)
- Creates a new ASCIIInputStream.
ASCIIInputStream Method
bad() | readChar() | readLong() |
eof() | readDouble() | readShort() |
flushLine() | readFloat() | readUnsignedByte() |
read(byte[]) | readFully(byte[]) | readUnsignedShort() |
read(byte[], int, int) | readFully(byte[], int, int) | readUTF() |
readBoolean() | readInt() | readWord() |
readByte() | readLine() | skipBytes(int) |
import java.io.*;
import sdsu.io.*;
class ReadingFileExample
{
public static void main( String args[] ) throws Exception
{
FileInputStream inputFile;
BufferedInputStream bufferedFile;
ASCIIInputStream cin;
inputFile = new FileInputStream( "ReadingFileExample.java" );
bufferedFile = new BufferedInputStream( inputFile );
cin = new ASCIIInputStream( bufferedFile );
System.out.println( cin.readWord() );
for ( int k = 1 ; k < 4; k++ )
System.out.println( cin.readLine() );
}
}
Output
import
sdsu.io.*;
import java.io.*;
class ReadingFileExample
UpperCaseInputStream Example
public static void main( String args[] ) throws Exception
{
InputStream input;
ASCIIInputStream cin;
input = new StringBufferInputStream( "hi mom how is dad?" );
input = new UpperCaseInputStream( input );
cin = new ASCIIInputStream( input );
System.out.println( cin.readWord() );
System.out.println( cin.readLine() );
Output
HI
MOM HOW IS DAD?
Creating New Streams
class UpperCaseInputStream extends FilterInputStream
{
public static final int EOF = -1;
public UpperCaseInputStream( InputStream input )
{
super( input ); // input is stored in field "in"
}
public int read() throws IOException
{
int nextChar = in.read();
if ( nextChar == EOF )
return EOF;
else
return toUpperCase( (char) nextChar );
}
public int read(byte bytes[], int offset, int length) throws
IOException
{
int charsRead = in.read(bytes, offset, length);
if ( charsRead == EOF )
return EOF;
for ( int index = offset; index < offset + charsRead; index++)
bytes[ index ] = toUpperCase( (char) bytes[ index ] ) ;
return charsRead;
}
protected byte toUpperCase( char convertMe ) {
return (byte) Character.toUpperCase( convertMe );
}
}
import java.io.*;
class WritingToFileExample
{
public static void main( String args[] ) throws Exception
{
FileOutputStream outputFile;
BufferedOutputStream bufferedFile;
PrintStream cout;
outputFile = new FileOutputStream( "LetterHome" );
bufferedFile = new BufferedOutputStream( outputFile );
cout = new PrintStream( bufferedFile );
cout.println( "Hi Mom" );
cout.println( "How is Dad?" );
cout.flush();
cout.close();
}
}