Title: Java Streams: Input and Output
1Java Streams Input and Output
- A input stream is an ordered sequence of units
of data coming into a program from a data source
(like a disk file, a socket, or input from the
terminal console). An output stream is a
sequence of data going out of program to an
external data destination (sink like a file,
a socket, output to the terminal.
- Input Stream To bring in information, a program
opens a stream on an information source (a file,
memory, a socket) and reads the information
sequentially, as shown here
File, or Terminal, or Socket
- Output Stream Similarly, a program can send
information to an external destination by opening
a stream to a destination and writing the
information out sequentially, like this
File, or Terminal, Or Socket
2Stream I/O Paradigm
- No matter where the data is coming from or going
to and no matter what its type, the algorithms
for sequentially reading and writing data are
basically the same - Reading
- open an input stream (setting up some stream
object to represent the source) - while more information (in the stream)
- read a unit of information from the stream object
- close the stream
- Writing
- open an output stream (setting up some stream
object to represent the destination) - while more information needs to be sent to stream
- write a data unit of information to the stream
object - close the stream
- Generally, I/O proceeds serially through the
stream, though some methods allow resetting
position. Generally, you pass through the data
in order, one unit at a time, starting at the
first unit, and proceeding until you get past the
last unit.
3Stream Taxonomy
- Streams can be for input (InputStreams or
Readers) or streams can be for output
(OutputStreams or Writers) - The data units of a stream can be oriented as
- Bytes (raw data 8 bits each)
- Characters (Text Unicode characters)
- The stream can be either
- Directly associated with the data source or data
sink - Usually provide very basic data reading/writing
methods - Provide some filtering property above and beyond
just getting the data from the source or to the
sink. - Filter streams usually provide buffering or
better methods for reading/writing data. - Filter streams are built atop existing streams
to add extra capabilities to the pre-existing
stream. As in - BufferedInputStream bis new
BufferedInputStream(new FileInputStream(myfile.tx
t)) - NOTE almost all stream IO constructors and
methods throw IOExceptions or subclasses of
IOException. You NEED TO handle these.
4Java Byte Streams
- Most raw data in files, sockets, or coming from
terminals is in plain byte form (in groups of 8
bits) must be processed with Java byte streams - Used when byte-by-byte reading or writing is
needed as with files that are just lists of raw
bits of data like image file, MS Word documents.
Or anything that has its own secret non-text
formatting. - Input Abstract Java class InputStream, with
very simple methods - int read( ) // reads next byte from stream and
returns byte value as an int - (returns -1 if no more data!) puts the byte as
the rightmost octet in the word - void close( ) // method you call to close the
stream - Two key non-abstract subclasses of InputStream
- FileInputStream(String filename) associated
with data source file - DataInputStream(InputStream) filter allows
input of formatted data. Example - void readDouble()
- Output Abstract class OutputStream, with simple
methods - void write(int byteData) // writes the byte,
stored in the int byteData, to the stream (the
byte that is written is the rightmost byte in the
word) - Void close( ) // method you call to close the
stream - Two key non-abstract subclasses of OutputStream
- FileOutputStream(String filename) associated
with the data sink (can create it or append to
it!) - DataOutputStream filter allows input of
formatted data. Example - double writeDouble(double db)
5Reading in a Picture File Byte Oriented Data
import java.io. public class
ReadPicture public static void main(String
args ) FileInputStream finsnull int
inbyte 0xff int bytecount 0 //
number of bytes read in if( args.length 0
) System.out.println("Usage\n\t java
readPicture filename\n") System.exit(0)
String filename args0 try fins new
FileInputStream(filename) catch(
FileNotFoundException e ) System.out.print(
"File Not found - no such file " filename)
System.exit(0) // now read in and display
the bytes - 24 at a time System.out.println("
Raw Byte Data of File ") try while(
(inbyte fins.read()) ! -1 )
System.out.print(Integer.toHexString(inbyte) "
") bytecount if( (bytecount24) 0
) System.out.println() fins.close()
catch( IOException e) System.out.printl
n("Got IO Exception Reading - byte number "
bytecount "\nCLOSING UP") System.ou
t.println("\n END OF DATA " bytecount "
bytes ")
6Byte-Oriented Output to a File Byte-wise File
Copy
import java.io. public class
CopyPicture public static void main(String
args ) FileInputStream finsnull
FileOutputStream fouts null int inbyte
0xff if( args.length lt 2 )
System.out.println("Usage\n\t java
CopyPicture sourcefile destfile\n")
System.exit(0) String sourcefile
args0 String destfile args1 try
fins new FileInputStream(sourcefile)
catch( FileNotFoundException e )
System.out.print("Source File Not found - no
such file " sourcefile) System.exit(0)
try fouts new FileOutputStream(destfile)
catch( FileNotFoundException e )
System.out.print("dest File Not opened "
destfile) System.exit(0) // now read
in and copy the bytes from fins to fouts try
while( (inbyte fins.read()) ! -1 )
fouts.write(inbyte)
fins.close() fouts.close() catch(
IOException e) System.out.println("Got IO
Exception Reading " "\nCLOSING
UP") System.exit(0)
7Using a Filtered Byte Stream To Save double Data
import java.io. public class SaveFibs int
numfibs 0 double fibs new
double50 public SaveFibs(int count) if(
count lt 2 ) System.exit(0) numfibs count
fibs0 0. fibs1 1. for( int i2 i lt
count i ) fibsi fibsi-1
fibsi-2 for(int i0 iltnumfibs i)
System.out.println("INIT fibs" i " "
fibsi) public static void main(String
args ) FileInputStream finsnull
FileOutputStream fouts null DataInputStream
dis null DataOutputStream dos
null if( args.length lt 1 ) System.out.p
rintln("Usage\n\t java SaveFibs
how-many-fibs\n") System.exit(0) Sav
eFibs me new SaveFibs(Integer.parseInt(args0)
) // create a file /temp/fibsx.dat (where x is
the count) // save the first x Fibonacci
numbers in this file as sequential //
doubles String filename "C\\temp\\fibs"
String.valueOf(me.numfibs) ".dat" System.out.
println("File Name is " filename) // code
continues on next slide
8Conclusion - Using a Filtered Byte Stream To
Save double Data
try fouts new FileOutputStream(filename
) dos new DataOutputStream(fouts) //
now write the numbers to the file for(int i0
i lt me.numfibs i) dos.writeDouble(me.fi
bsi) dos.close() catch(IOExcepti
on e) e.printStackTrace()
System.exit(0) // now check if it worked
by reading them in and printing // them
out try fins new FileInputStream(filename
) dis new DataInputStream(fins) // read
the number from the file int fibcount
0 while( true )
System.out.println("ReadBack fib" fibcount
" " dis.readDouble() )
fibcount catch( EOFException e)
System.out.println("EOF Encountered")
catch( IOException e) e.printStackTra
ce() System.exit(0) // end main( )
// end class SaveFibs
9Java Character Streams
- Units of data in streams are individual Unicode
characters. All processing is in characters. - Usually character-by-character reading or
writing, but can also be line-oriented (using a
filter stream). - Applies to text-oriented files and sockets (like
.txt, .html, source code files, sockets talking
text-protocols like HTTP, SMTP, SIP, etc.). - Input abstract Java class Reader, with very
simple method - int read( ) // reads next character from stream
and returns value as an int - (returns -1 if no more data!) throws
IOException - Character returned in placed in rightmost two
octets of the returned int - void close( ) // method you call to close the
stream - Three key non-abstract subclasses of Reader
- InputStreamReader(InputStream) converts byte
stream to character stream - FileReader( String filename) extends
InputStreamReader - associated with data source
file. Disk file storage is byte oriented. - BufferedReader(Reader) filtered stream, allows
line-oriented input with method - String readLine( ) // reads next line of
character input, returns null at EOF
10Unicode Character IO Problems
Outside JVM Characters treated as 7 0r 8 bit
bytes via some coding scheme (ASCII, ISO, UTF
versions) This includes data in Disk files,
data on sockets, and terminal input or output
InputStreamReader
InputStream
Inside JVM Characters treated as Unicode special
16 bit storage
OutputStream
OutputStreamWriter
11Java Character Streams for Output
- Output Abstract class Writer, with simple
methods - void write(int data) // writes the character,
stored in the int data, to the stream - Void close( ) // method you call to close the
stream - Three key non-abstract subclasses of Reader
- OutputStreamWriter(OutputStream) converts
character stream to byte stream - FileWriter( String filename) extends
OutputStreamWriter - associated with data
destination (sink) file. Disk file storage is
byte oriented. - PrintWriter(Writer) filtered stream, allows
line-oriented output with method - void println( datatype arg ) // writes next line
of character output - void print(datatype arg ) // writes formatted
character data to output stream - Example given that pw is a PrintWriter, we can
say pw.println(Hello)
Output Stream of Unicode Characters from program
OutputStreamWriter(S) write( )
Output Stream of bytes to Data sink S
Unicode characters being output from program
FileWriter( FN ) write( )
Stream of bytes to disk file FN
12Reading a Text File into a Program
// Reading a text file - character IO import
java.io. public class ReadTextFile public
static void main(String args) FileReader
fr null BufferedReader bfr null String
inline null // open the file given in the
command line and display it String filename
args0 try fr new FileReader(filename)
// could have used fr new
InputStreamReader(new FileOutputStream(filename))
// could read this file a character at a time
with fr.read(), but let's // read it a whole
line at a time bfr new BufferedReader(fr)
System.out.println(" Display of Text File
" filename " ") while((inline
bfr.readLine()) ! null) // display the
line read in System.out.println(inline)
System.out.println(" END OF FILE
") bfr.close() catch(
IOException e ) System.out.println("Got
another IO Exception opening/reading file "
filename) e.printStackTrace()
System.exit(0)
13Converting Bytes from Terminal Into Line-Oriented
Character Input
- Note that input typed into the terminal console
is byte-oriented. - To read in Strings (lines) from the terminal,
need to convert input into a character stream. - import java.io.
- public class TerminalEcho
-
- public static void main(String args ) throws
IOException -
- String inline null
- InputStreamReader isr BufferedReader bfr
- isr new InputStreamReader( System.in )
- bfr new BufferedReader(isr)
-
- try
-
- while( (inlinebfr.readLine()).length() ! 0 )
-
- System.out.println("ECHO " inline)
-
14Saving Input from the Terminal Into a Text
(Character) File
- Using println( ) to write to file
- import java.io.
- public class SaveInputToFile
-
- public static void main(String args ) throws
IOException -
- String inline null
- InputStreamReader isrnull BufferedReader
bfrnull - FileWriter fwnull PrintWriter pwnull
- isr new InputStreamReader( System.in )
- bfr new BufferedReader(isr)
- try
- String unique String.valueOf(System.currentTi
meMillis()) - System.out.println("unique " unique)
- fw new FileWriter("C\\temp\\saveit"
unique ".txt") - pw new PrintWriter(fw)
-
- catch( IOException e)
15Advice on Text and Other IO
- Text IO Applies if you are dealing with any
source or sink that is textual in nature. This
applies if you have a socket that talks an ASCII
oriented protocol (like HTTP, FTP, etc.), or any
file.txt or file.html, or characters from the
terminal, etc. - Store the internal data (that you deal with for
this source or sink) as Unicode characters, using
data type char. - For input from the text oriented source
- For files use FileReader fr new
FileReader(myfile.txt) // file had better
exist - int c fr.read( )
(reads next character from file into location c) - BufferedReader br
new BufferedReader(fr) - String s
br.readLine( ) (reads whole line of text from
file into s) - Terminal input Note that System.in is an
InputStream. So we make an InputStreamReader out
of it and then wrap that in a BufferedReader (if
you want to read a line at a time
InputStreamReader isr new InputStreamReader(Syst
em.in) - int c
isr.read( ) // brings in the next character
from the terminal -
BufferedReader br new BufferedReader(isr) -
String s br.readLine( ) // reads next line of
text from terminal into s - Socket input Given that you have a socket sock,
you need to get an input stream for that socket.
To do this use - InputStream sis sock.getInputStream( )
- InputStreamReader isr new
InputStreamReader( sis ) - int c isr.read( ) // brings next
character from socket into the variable c - BufferedReader br new BufferedReader(
isr ) - String s br.readLine( ) // reads next
line of text from socket into s
16Advice on Text and Other IO - Continued
- For output to a text oriented stream
- For files use FileWriter fw new
FileWriter(myfile.txt) // file can be created - fw.write(int c) (Writes the character
stored in c to the file) - PrintWriter pw new PrintWriter(fw)
- pw.println(String s) (Writes all
characters of the string s to the file) - Terminal output Just use System.out and its
print( ) and println( ) methods! - Socket output Given that you have a socket sock,
you need to get an output stream for that socket.
To do this use - OutputStream sos sock.getOutputStream( ).
- To write a character at a time, to the
socket OutputStreamWriter osw new
OutputStreamWriter(sos) - then say osw.write(int c) to write the
character stored in c to the socket - To write a line-at-a-time of text to that
socket PrintWriter pw new PrintWriter(osw) - then use pw.println(String s)
- Non Text IO
- This applies to sources and sinks that have
non-textually formatted data, like bit-streams of
a JPEG, or of a GIF encoding a picture, or a
Microsoft Word or Excel document, or raw
bit-streams on a socket, etc. - Best to simply group 8 bits-at-a-time as a byte
and do your IO with byte-oriented streams.
Internal data best stored as byte or as int.
Use the basic InputStream and OutputStream and
their file counterparts. You can put a buffered
stream over it for more efficiency. As for the
actual IO, use basic read( ) and write( ) and do
it one byte at a time. - Slide 6 has an example you should try to extend
that program to use Buffered Streams, using
fins new BufferedInputStream(new
FileInputStream(sourcefile)) and
fouts new
BufferedOutputStream( new FileOutputStream(destfil
e) -