Title: Chapter 12: JAVA IO System
1Chapter 12 JAVA IO System
- IO library design is challenging
- Many input and output devices (console, file,
network, etc.) - Many formats (binary, character, by lines, by
words, etc.) - Many ways (sequential, random access, buffered)
- JAVA provides a lot of classes for IO
2File class
- To abstract access to files on disk, JAVA
provides a File class - A File object can refer to a single file on disk
or to a list of files on disk (a directory
listing)
3File class example
public static void main(String args)
File path new File(".") String list
if(args.length 0) list path.list()
else list path.list(new
DirFilter(args0)) Arrays.sort(list, new
AlphabeticComparator()) for(int i 0 i lt
list.length i) System.out.println(listi
) class DirFilter implements
FilenameFilter private Pattern pattern
public DirFilter(String regex) pattern
Pattern.compile(regex) public boolean
accept(File dir, String name) // Strip path
information, search for regex return
pattern.matcher( new File(name).getName()).m
atches() ///
4Some other File class methods
public class MakeDirectories private static
Test monitor new Test() private static void
usage() System.err.println(
"UsageMakeDirectories path1 ...\n"
"Creates each path\n" "UsageMakeDirectori
es -d path1 ...\n" "Deletes each path\n"
"UsageMakeDirectories -r path1 path2\n"
"Renames from path1 to path2")
System.exit(1) private static void
fileData(File f) System.out.println(
"Absolute path " f.getAbsolutePath()
"\n Can read " f.canRead() "\n Can
write " f.canWrite() "\n getName "
f.getName() "\n getParent "
f.getParent() "\n getPath "
f.getPath() "\n length " f.length()
"\n lastModified " f.lastModified())
if(f.isFile()) System.out.println("It's a
file") else if(f.isDirectory())
System.out.println("It's a directory")
5Some other File class methods (cont.)
public static void main(String args)
if(args.length lt 1) usage()
if(args0.equals("-r")) if(args.length
! 3) usage() File old new
File(args1), rname new
File(args2) old.renameTo(rname)
fileData(old) fileData(rname)
return // Exit main int count 0
boolean del false if(args0.equals("-d"))
count del true
count--
6Some other File class methods (cont.)
while(count lt args.length) File f
new File(argscount) if(f.exists())
System.out.println(f " exists")
if(del) System.out.println("deleting..
." f) f.delete()
else // Doesn't exist if(!del)
f.mkdirs() System.out.println("
created " f)
fileData(f) if(args.length 1
args0.equals("MakeDirectoriesTest"))
7JAVA IO Library
- InputStream and Reader are top classes in Java IO
hierarchy. They provide read method that can be
use to read a single bye or array of bytes - OutputStream and Writer are top classes in Java
IO hierarchy. They provide write method to write
a single bye or an array of bytes - Other lower classes provides more usefull
functionality than those povided by these top
classes - So in programming normally we use lower classes
8Types of InputStream
9Types of InputStream (cont.)
10Types of OutputStream
11Uses of FilterInputStream and FilterOutputStream
- Basic IO classes in JAVA provides very primitive
functionality which is not very useful. For
example to read a String we need to read a series
of bytes (into an array) and then convert them to
a single String. - To provide higher level functionality, Java uses
decorator design pattern and uses Filter classes. - Decorator design pattern provides a way to add
functionlaity to classes in a transparant way. So
if we have an InputStream then a
FilterInputStream adds some (usefull)
functionality to it without affecting its basic
functionality
12Reading from an InputStream with FilterInputStream
13Reading from an InputStream with
FilterInputStream (cont.)
14Writing to an OutputStream with FilterOutputStream
15Readers and Writers
- Reader and Writer classes were added in Java 1.1
- They provide character oriented I/O (Streams
provides byte oriented I/O) - They are unicode compliant which is necessary
for internationalization - In programs it is a good practice to first try
to user Reader and Writer classes instead of
Stream classes - However in some situation you must use Stream
classes (like processing a zip file)
16Correspondence of Streams and Reader/Writer
classes
17Corresponding filters
18Typical I/O uses
// 1. Reading input by lines BufferedReader in
new BufferedReader( new
FileReader("IOStreamDemo.java")) String s, s2
new String() while((s in.readLine())! null)
s2 s "\n" in.close()
19Typical I/O uses (cont.)
// 1b. Reading standard input BufferedReader
stdin new BufferedReader(
new InputStreamReader(System.in))
System.out.print("Enter a line")
System.out.println(stdin.readLine())
20Typical I/O uses (cont.)
// 2. Input from memory StringReader in2 new
StringReader(s2) int c while((c in2.read())
! -1) System.out.print((char)c)
21Typical I/O uses (cont.)
// 3. Formatted memory input try
DataInputStream in3 new DataInputStream(
new ByteArrayInputStream(s2.getBytes()))
while(true) System.out.print((char)in3.re
adByte()) catch(EOFException e)
System.err.println("End of stream")
22Typical I/O uses (cont.)
// 4. File output try BufferedReader in4
new BufferedReader( new
StringReader(s2)) PrintWriter out1 new
PrintWriter( new
BufferedWriter(new FileWriter("IODemo.out")))
int lineCount 1 while((s in4.readLine())
! null ) out1.println(lineCount " "
s) out1.close() catch(EOFException e)
System.err.println("End of stream")
23Typical I/O uses (cont.)
// 5. Storing recovering data try
DataOutputStream out2 new DataOutputStream(
new BufferedOutputStream( new
FileOutputStream("Data.txt")))
out2.writeDouble(3.14159)
out2.writeUTF("That was pi")
out2.writeDouble(1.41413)
out2.writeUTF("Square root of 2")
out2.close() DataInputStream in5 new
DataInputStream( new BufferedInputStream(
new FileInputStream("Data.txt")))
// Must use DataInputStream for data
System.out.println(in5.readDouble()) //
Only readUTF() will recover the // Java-UTF
String properly System.out.println(in5.read
UTF()) // Read the following double and
String System.out.println(in5.readDouble())
System.out.println(in5.readUTF())
catch(EOFException e) throw new
RuntimeException(e)
24Typical I/O uses (cont.)
// 6. Reading/writing random access files
RandomAccessFile rf new
RandomAccessFile("rtest.dat", "rw") for(int
i 0 i lt 10 i) rf.writeDouble(i1.414)
rf.close() rf new RandomAccessFile("rtes
t.dat", "rw") rf.seek(58)
rf.writeDouble(47.0001) rf.close() rf
new RandomAccessFile("rtest.dat", "r")
for(int i 0 i lt 10 i)
System.out.println("Value " i " "
rf.readDouble()) rf.close()
25Making a file handling utility
package com.bruceeckel.util import
java.io. import java.util. public class
TextFile extends ArrayList // Tools to read
and write files as single strings public
static String read(String fileName) throws
IOException StringBuffer sb new
StringBuffer() BufferedReader in new
BufferedReader(new FileReader(fileName))
String s while((s in.readLine()) ! null)
sb.append(s) sb.append("\n")
in.close() return sb.toString()
public static void write(String fileName,
String text) throws IOException PrintWriter
out new PrintWriter( new
BufferedWriter(new FileWriter(fileName)))
out.print(text) out.close()
26Making a file handling utility (cont.)
public TextFile(String fileName) throws
IOException super(Arrays.asList(read(fileNam
e).split("\n"))) public void write(String
fileName) throws IOException PrintWriter
out new PrintWriter( new
BufferedWriter(new FileWriter(fileName)))
for(int i 0 i lt size() i)
out.println(get(i)) out.close() //
Simple test public static void main(String
args) throws Exception String file
read("TextFile.java") write("test.txt",
file) TextFile text new TextFile("test.txt"
) text.write("test2.txt")
27Reading from standard input
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()) ! null s.length() ! 0)
System.out.println(s) // An empty line or
Ctrl-Z terminates the program
28Redirecting standard I/O
public class Redirecting // Throw exceptions
to console public static void main(String
args) throws IOException PrintStream
console System.out BufferedInputStream in
new BufferedInputStream( new
FileInputStream("Redirecting.java"))
PrintStream out new PrintStream( new
BufferedOutputStream( new
FileOutputStream("test.out")))
System.setIn(in) System.setOut(out)
System.setErr(out) BufferedReader br new
BufferedReader( new InputStreamReader(System
.in)) String s while((s
br.readLine()) ! null) System.out.println(s
) out.close() // Remember this!
System.setOut(console)
29JAVA new IO - nio
- Introduced in JDK 1.4 in java.nio. packages
- The main goal is speed of I/O operation
- It does it by providing I/O facilities that are
more near the way operating systesm does I/O
operations - It does it by introducing channels and buffers
- FileInputStream, FileOutputStream and
RandomAccessFile from old java IO library have
been modified to produce a FileChannel
30Java neo IO - example
import java.nio.channels. public class
GetChannel private static final int BSIZE
1024 public static void main(String args)
throws Exception // Write a file
FileChannel fc new FileOutputStream("data.
txt").getChannel() fc.write(ByteBuffer.wrap("
Some text ".getBytes())) fc.close() //
Add to the end of the file fc new
RandomAccessFile("data.txt", "rw").getChannel()
fc.position(fc.size()) // Move to the end
fc.write(ByteBuffer.wrap("Some more".getBytes()))
fc.close() // Read the file fc
new FileInputStream("data.txt").getChannel()
ByteBuffer buff ByteBuffer.allocate(BSIZE)
fc.read(buff) buff.flip()
while(buff.hasRemaining())
System.out.print((char)buff.get())
31File copy using channels
public class ChannelCopy private static final
int BSIZE 1024 public static void
main(String args) throws Exception
if(args.length ! 2) System.out.println("a
rguments sourcefile destfile")
System.exit(1) FileChannel in
new FileInputStream(args0).getChannel(),
out new FileOutputStream(args1).getChannel()
ByteBuffer buffer ByteBuffer.allocate(BSIZE)
while(in.read(buffer) ! -1)
buffer.flip() // Prepare for writing
out.write(buffer) buffer.clear() //
Prepare for reading
32Better way for file copy using transferTo()
public class TransferTo public static void
main(String args) throws Exception
if(args.length ! 2) System.out.println("a
rguments sourcefile destfile")
System.exit(1) FileChannel in
new FileInputStream(args0).getChannel(),
out new FileOutputStream(args1).getChannel()
in.transferTo(0, in.size(), out) // Or
// out.transferFrom(in, 0, in.size())
33View buffers
public class IntBufferDemo private static
Test monitor new Test() private static final
int BSIZE 1024 public static void
main(String args) ByteBuffer bb
ByteBuffer.allocate(BSIZE) IntBuffer ib
bb.asIntBuffer() // Store an array of int
ib.put(new int 11, 42, 47, 99, 143, 811,
1016 ) // Absolute location read and
write System.out.println(ib.get(3))
ib.put(3, 1811) ib.rewind()
while(ib.hasRemaining()) int i
ib.get() if(i 0) break // Else we'll
get the entire buffer System.out.println(i)
monitor.expect(new String
"99", "11", "42", "47",
"1811", "143", "811", "1016"
) ///
34Endians
public class Endians private static Test
monitor new Test() public static void
main(String args) ByteBuffer bb
ByteBuffer.wrap(new byte12)
bb.asCharBuffer().put("abcdef")
System.out.println(Arrays2.toString(bb.array()))
bb.rewind() bb.order(ByteOrder.BIG_ENDIAN
) bb.asCharBuffer().put("abcdef")
System.out.println(Arrays2.toString(bb.array()))
bb.rewind() bb.order(ByteOrder.LITTLE_END
IAN) bb.asCharBuffer().put("abcdef")
System.out.println(Arrays2.toString(bb.array()))
monitor.expect(new String "0, 97,
0, 98, 0, 99, 0, 100, 0, 101, 0, 102",
"0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102",
"97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102,
0" )
35Buffer interface
36Example of buffer functionality
public class UsingBuffers private static Test
monitor new Test() private static void
symmetricScramble(CharBuffer buffer)
while(buffer.hasRemaining())
buffer.mark() char c1 buffer.get()
char c2 buffer.get() buffer.reset()
buffer.put(c2).put(c1) public
static void main(String args) char data
"UsingBuffers".toCharArray() ByteBuffer bb
ByteBuffer.allocate(data.length 2)
CharBuffer cb bb.asCharBuffer()
cb.put(data) System.out.println(cb.rewind())
symmetricScramble(cb)
System.out.println(cb.rewind())
symmetricScramble(cb) System.out.println(cb.r
ewind()) monitor.expect(new String
"UsingBuffers", "sUniBgfuefsr",
"UsingBuffers" )
37Memory mapped files
public class LargeMappedFiles static int
length 0x8FFFFFF // 128 Mb public static
void main(String args) throws Exception
MappedByteBuffer out new
RandomAccessFile("test.dat", "rw").getChannel()
.map(FileChannel.MapMode.READ_WRITE, 0,
length) for(int i 0 i lt length i)
out.put((byte)'x') System.out.println("Finis
hed writing") for(int i length/2 i lt
length/2 6 i) System.out.print((char)ou
t.get(i))
38Performance test
- In the book, ther is a test program that
demonstrates that memory mapped files show better
performance
Stream Write 1719 Mapped Write 359 Stream Read
750 Mapped Read 125 Stream Read/Write
5188 Mapped Read/Write 16
39File locking
public class FileLocking public static void
main(String args) throws Exception
FileOutputStream fos new FileOutputStream("file.t
xt") FileLock fl fos.getChannel().tryLock()
if(fl ! null) System.out.println("L
ocked File") Thread.sleep(100)
fl.release() System.out.println("Released
Lock") fos.close()
40Compression related classes
41Simple compression with GZIP
BufferedReader in new BufferedReader(
new FileReader(args0)) BufferedOutputStream
out new BufferedOutputStream( new
GZIPOutputStream( new FileOutputStream("te
st.gz"))) System.out.println("Writing
file") int c while((c in.read()) !
-1) out.write(c) in.close()
out.close() System.out.println("Reading
file") BufferedReader in2 new
BufferedReader( new InputStreamReader(new
GZIPInputStream( new FileInputStream("test
.gz")))) String s while((s
in2.readLine()) ! null) System.out.println(
s)
42JAR (Java Archieve) files
- jar files are zip files with .jar suffix
- We use them to compress and group a number of
classes into a single file - This is a convenient way for libraries and
transfering applets over internet - With the jar utility you can make a jar file
- jar options destination manifest
inputfile(s)
43Object serialization
- Using Object Serialization we can store an image
of an object to a file or transfer it through a
network connection - This is a mechanism we need to do Remote Method
Invocation (RMI) - Also it is helpful to persist some objects and
use them later - For an object to be serialized, the object
should implement Serializable interface - ObjectOutputStream and ObjectInputStream can be
used to serialize and de-serialize objects
44Object serialization code fragment
public class Worm implements Serializable //
body of the class // .... ObjectOutputStream
out new ObjectOutputStream( new
FileOutputStream("worm.out")) out.writeObject("Wo
rm storage\n") out.writeObject(w)
out.close() // Also flushes output
ObjectInputStream in new ObjectInputStream(
new FileInputStream("worm.out")) String s
(String)in.readObject() Worm w2
(Worm)in.readObject()
45Contolling object serialization
Serializabe interface is good when we want to
serialize full object (a web of objects which are
included in the serialized object) To control
which members are serialized, we can use
Externalizable interface (see samples in the
book) Also we can use transient keyword for data
members that we don't want serialized (see sample
in the book) public class Logon
implements Serializable private
Date date new Date() private
String username private transient
String password // rest of the class
46Regular expressions
- Regualr expressions are powerful and flexible
text processing tools - Using pattern matching with regular expressions
we can find complex patterns in Strings - We have seen the usage of regular expressions
inside expect method calls
47Regular expression constructs (not complete)
48Regular expression constructs (not complete)
(cont.)
49Pattern and Matcher
public class TestRegularExpression public
static void main(String args)
if(args.length lt 2) System.out.println("Us
age\n" "java TestRegularExpression "
"characterSequence regularExpression")
System.exit(0)
System.out.println("Input \"" args0
"\"") for(int i 1 i lt args.length i)
System.out.println( "Regular
expression \"" argsi "\"") Pattern
p Pattern.compile(argsi) Matcher m
p.matcher(args0) while(m.find())
System.out.println("Match \"" m.group()
"\" at positions " m.start()
"-" (m.end() - 1))
50Groups
public class Groups private static Test
monitor new Test() static public final
String poem "Twas brillig, and the slithy
toves\n" "Did gyre and gimble in the
wabe.\n" "All mimsy were the borogoves,\n"
"And the mome raths outgrabe.\n\n"
"Beware the Jabberwock, my son,\n" "The
jaws that bite, the claws that catch.\n"
"Beware the Jubjub bird, and shun\n" "The
frumious Bandersnatch." public static void
main(String args) Matcher m
Pattern.compile("(?m)(\\S)\\s((\\S)\\s(\\S))
") .matcher(poem) while(m.find())
for(int j 0 j lt m.groupCount() j)
System.out.print("" m.group(j) "")
System.out.println()
51Groups (cont.)
monitor.expect(new String "the
slithy toves" "theslithy
tovesslithytoves", "in the
wabe.inthe wabe.thewabe.", "were
the borogoves," "werethe
borogoves,theborogoves,", "mome raths
outgrabe." "momeraths
outgrabe.rathsoutgrabe.",
"Jabberwock, my son," "Jabberwock,my
son,myson,", "claws that catch."
"clawsthat catch.thatcatch.",
"bird, and shunbird,and shunandshun",
"The frumious Bandersnatch.The"
"frumious Bandersnatch.frumiousBandersnatch.
" )
52Split()
public class SplitDemo private static Test
monitor new Test() public static void
main(String args) String input
"This!!unusual use!!of exclamation!!points"
System.out.println(Arrays.asList(
Pattern.compile("!!").split(input))) // Only
do the first three System.out.println(Arrays.
asList( Pattern.compile("!!").split(input,
3))) System.out.println(Arrays.asList(
"Aha! String has a split() built in!".split("
"))) monitor.expect(new String
"This, unusual use, of exclamation, points",
"This, unusual use, of exclamation!!points",
"Aha!, String, has, a, split(), built,
in!" )