Object-Oriented Programming 95-712
description
Transcript of Object-Oriented Programming 95-712
Object-Oriented ProgrammingObject-Oriented Programming95-71295-712
MISM/MSITMISM/MSIT
Carnegie Mellon UniversityCarnegie Mellon University
Lecture 10: I/O, RTTILecture 10: I/O, RTTI
Today’s TopicsToday’s Topics
The The FileFile class class Using command line argumentsUsing command line arguments More on the Java I/O classesMore on the Java I/O classes The The SimpleInputSimpleInput class, in detail class, in detail Java’s compression classes (briefly)Java’s compression classes (briefly) Run-time type identification (RTTI)Run-time type identification (RTTI) A little on javadocA little on javadoc
The The FileFile Class Class
Think of this as holding a file Think of this as holding a file namename, or a list , or a list of file of file namesnames (as in a directory). (as in a directory).
You create one by giving the constructor a You create one by giving the constructor a pathname, as inpathname, as inFile f = new File(D:\Together5.02\myprojects\JavaCourse\Week9\File f = new File(D:\Together5.02\myprojects\JavaCourse\Week9\
DirList\.);DirList\.);
This is a directory, so now the This is a directory, so now the FileFile ff holds a holds a list of (the names of) files in the directory.list of (the names of) files in the directory.
It’s straightforward to print them out.It’s straightforward to print them out.
Listing FilesListing Filesimport java.io.*;import java.util.*;public class DirList { public static void main(String[] args) { File path = new File("."); String[] list; System.out.println(path.getAbsolutePath()); if(args.length == 0) list = path.list(); else list = path.list(new DirFilter(args[0])); for (int i = 0; i < list.length; i++) System.out.println(list[i]); }}
With No Command Line Args…With No Command Line Args…
D:\Together5.02\myprojects\JavaCourse\Week9\DirList\.default.dfPackagedefault.dfPackage.wmfDirFilter.javaDirList.javaDirList.tprDirList.tws
With “.java” on the Command LineWith “.java” on the Command Line
D:\Together5.02\myprojects\JavaCourse\Week9\DirList\.DirFilter.javaDirList.java
DirFilterDirFilter is a is a FilenameFilterFilenameFilter
Its only method is Its only method is accept()accept()::
import java.io.*;import java.util.*;
public class DirFilter implements FilenameFilter { String afn; DirFilter(String afn) { this.afn = afn; } public boolean accept(File dir, String name) { String f = new File(name).getName(); return f.indexOf(afn) != -1; }}
Using the “args” in Using the “args” in main()main()
All this time we’ve been dumbly typingAll this time we’ve been dumbly typingpublic static void main(String[] args) {public static void main(String[] args) {……
argsargs is an array of is an array of StringStrings, but for us it’s s, but for us it’s usually been empty.usually been empty.
It contains any It contains any command line parameterscommand line parameters we choose to include.we choose to include.
If we’re at a DOS or Unix command line, If we’re at a DOS or Unix command line, we might type we might type >java DirList .java>java DirList .java
In Together, we set the Run ConfigurationIn Together, we set the Run Configuration
Setting the Run ConfigurationSetting the Run Configuration
Other Other FileFile Methods Methods
canRead()canRead() canWrite()canWrite() exists()exists() getParent()getParent() isDirectory()isDirectory() isFile()isFile() lastModified()lastModified() length()length()
FileFile Methods for Modifying Methods for Modifying
createNewFile()createNewFile() delete()delete() makeDir()makeDir() makeDirs()makeDirs() renameTo()renameTo() setLastModified()setLastModified() setReadOnly()setReadOnly()
More on InputMore on Input
All of thesereturn bytes!
InputStream
read():intread():byte[]
FilterInputStream
read():int
FileInputStream
read():int
ObjectInputStream
readObject():Object
BufferedInputStream
read():int
DataInputStream
readByte():bytereadChar():charreadDouble():doublereadInt():int
InflatorInputStream
read():int
FilterInputStreamFilterInputStream JavaDoc JavaDoc
A FilterInputStream contains some other input A FilterInputStream contains some other input stream, which it uses as its basic source of data, stream, which it uses as its basic source of data, possibly transforming the data along the way or possibly transforming the data along the way or providing additional functionality. providing additional functionality.
The class FilterInputStream itself simply overrides The class FilterInputStream itself simply overrides all methods of InputStream with versions that pass all methods of InputStream with versions that pass all requests to the contained input stream. all requests to the contained input stream.
Subclasses of FilterInputStream may further Subclasses of FilterInputStream may further override some of these methods and may also override some of these methods and may also provide additional methods and fields.provide additional methods and fields.
ReadersReadersReader
read():int
BufferedReader StringReaderInputStreamReader
FileReader
These returnchars!
We Saw These Last TimeWe Saw These Last Time
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
InputStreamReader isr = new InputStreamReader(new
FileInputStream("FileInput.java")); //slow: unbuffered
This is easier (if we’re happy with the default character encoding and buffer size:
InputStreamReader isr = new FileReader(" FileInput.java");
OutputStreamOutputStreams and s and WriterWriterss Basically, a “mirror image” of Basically, a “mirror image” of
InputStreamInputStreams and s and ReaderReaders.s. Wrapping is the same, e.g.,Wrapping is the same, e.g.,
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); String s; try { while ((s = br.readLine()).length() != 0) { bw.write(s, 0, s.length()); bw.newLine(); bw.flush(); } }
FileWriterFileWriter
Again, basically the same. The constructors areAgain, basically the same. The constructors are– FileWriter(File file)FileWriter(File file)
– FileWriter(FileDescriptor fd)FileWriter(FileDescriptor fd)
– FileWriter(String s)FileWriter(String s)
– FileWriter(String s, boolean append)FileWriter(String s, boolean append)
The last one allows appending, rather than writing The last one allows appending, rather than writing to the beginning (and erasing an existing file!).to the beginning (and erasing an existing file!).
These These willwill create files! create files! There is also There is also PrintWriterPrintWriter
PrintWriterPrintWriter PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Test.txt"))); String s; try { while ((s = br.readLine()).length() != 0) { bw.write(s, 0, s.length()); bw.newLine(); bw.flush(); out.println(s); //out.flush(); } } catch(IOException e) { } out.close(); // also flushes
The The SimpleInputSimpleInput Class Class
You’ve used this class (by David Barnes) a number of You’ve used this class (by David Barnes) a number of times, now let’s examine it.times, now let’s examine it.
The idea is to make it easy to open a file, and provide The idea is to make it easy to open a file, and provide methods likemethods like– short nextShort()short nextShort()– double nextDouble()double nextDouble()– ……all the other primitive typesall the other primitive types– String nextWord()String nextWord()– String nextLine()String nextLine()– String getDelimiters()String getDelimiters()– void setDelimiters(String)void setDelimiters(String)
The “file” could be The “file” could be System.inSystem.in..
SimpleInputSimpleInput (cont.) (cont.)
This functionality is provided in C++ by the This functionality is provided in C++ by the standard iostream library. Why something standard iostream library. Why something similar isn’t “stock” in Java mystifies me…similar isn’t “stock” in Java mystifies me…
SimpleInputSimpleInput uses the uses the StringTokenizerStringTokenizer classclass
The The StreamTokenizerStreamTokenizer class is similar, but class is similar, but with more features (and some drawbacks).with more features (and some drawbacks).
What’s a “token”? Any sequence of non-What’s a “token”? Any sequence of non-delimiter characters.delimiter characters.
StringTokenizerStringTokenizer Example Example
StringTokenizer st = new StringTokenizer("this is a test");while (st.hasMoreTokens()) { println(st.nextToken());}
This prints: thisisatest
The default delimiter string is " \t\n\r\f"
How Does It Work?How Does It Work?
t h i s i s a t e s t
Tokenizer initialized with a String:
delimiters { \t\n\r\f}
Call nextToken(); search forward for next non-delimiter, and remember its position
t h i s i s a t e s t delimiters { \t\n\r\f}
(A very short search this time!)
How Does It Work (cont.)How Does It Work (cont.)
t h i s i s a t e s t delimiters { \t\n\r\f}
Search forward for next delimiter, and remember its position
t h i s i s a t e s t delimiters { \t\n\r\f}
Create and return the substring between these two positions.
t h i s
The Basic PlanThe Basic Plan
A A StringTokenizerStringTokenizer holds the current line. holds the current line. Upon a request for a token:Upon a request for a token:
– if there are tokens remaining in the current line, try to if there are tokens remaining in the current line, try to convert the next token to the desired type, and return itconvert the next token to the desired type, and return it
– otherwise, skip and try to convert the next tokenotherwise, skip and try to convert the next token
– otherwise, read a new line, and try againotherwise, read a new line, and try again
Upon a request for the next line:Upon a request for the next line:– discard the “left-over” linediscard the “left-over” line
– read a new line and return itread a new line and return it
Private VariablesPrivate Variables
import java.io.*;import java.util.StringTokenizer;
public class SimpleInput { private static final BufferedReader stdinReader = new BufferedReader(new InputStreamReader(System.in)); private BufferedReader reader = stdinReader; private String delimiters = " "; private StringTokenizer tokenizer = new StringTokenizer("");}
Private VariablesPrivate Variables
This illustrates the way that Java This illustrates the way that Java implements “default values”.implements “default values”.
A class simply initializes member variables A class simply initializes member variables to default values in its class declaration, and to default values in its class declaration, and leaves it to a constructor to change the leaves it to a constructor to change the defaults as required.defaults as required.
This is equivalent to the C++ technique of This is equivalent to the C++ technique of default constructor arguments.default constructor arguments.
There are “set `n get” methods for these:There are “set `n get” methods for these:
Private vs. Public Set `n GetsPrivate vs. Public Set `n Gets
private BufferedReader getReader() { return reader; }
private void setReader(BufferedReader r) { reader = r; }
private StringTokenizer getTokenizer() { return tokenizer; }
private void setTokenizer(StringTokenizer t) { tokenizer = t; }
public String getDelimiters() { return delimiters; }
public void setDelimiters(String d) { if ((d != null) && (d.length() > 0)) delimiters = d; }
SimpleInputSimpleInput Constructors Constructors public SimpleInput() { // uses standard input } public SimpleInput(String file) throws RuntimeException { File details = new File(file); if (!details.exists()) throw new RuntimeException(file + " does not exist."); else if (!details.canRead()) throw new RuntimeException(file + " exists but is unreadable."); else if (!details.isFile()) throw new RuntimeException(file + " is not a regular file."); else { try { setReader(new BufferedReader(new FileReader(details))); } catch (FileNotFoundException e) { throw new RuntimeException("Failed to open " + file + " for unknown reason."); } } }
getLine()getLine() (Note It’s (Note It’s publicpublic))
public String nextLine() throws RuntimeException { try { discardLine(); BufferedReader reader = getReader(); String line = reader.readLine(); //if (line == null) // throw new RuntimeException("End of input."); return line; } catch (IOException e) { // pass it on as an unchecked exception throw new RuntimeException(e.getMessage()); } }
Is EOF An Exception?Is EOF An Exception?
Exceptions are things we don’t expect will Exceptions are things we don’t expect will ever happen.ever happen.
But EOF happens for every file!But EOF happens for every file! Is Is nullnull an OK thing to return from an OK thing to return from
getLine()getLine()?? Isn’t Isn’t nullnull just what a just what a ReaderReader returns? returns? Will this cause problems elsewhere?Will this cause problems elsewhere?
Now Now nextToken()nextToken()
private String nextToken() throws RuntimeException { StringTokenizer t = getTokenizer(); final String delimiters = getDelimiters(); if (!t.hasMoreTokens()) { do { String line = nextLine(); //could throw exception t = new StringTokenizer(line, delimiters); setTokenizer(t); } while (!t.hasMoreTokens()); } return t.nextToken(delimiters); // could throw exception }
nextWord(), nextBoolean()nextWord(), nextBoolean()
public String nextWord() throws RuntimeException { return nextToken(); }
public boolean nextBoolean() throws RuntimeException { for ( ; ; ) { String s = nextWord(); if (s.equalsIgnoreCase("t") || s.equalsIgnoreCase("true")) return true; else if (s.equalsIgnoreCase("f") || s.equalsIgnoreCase("false")) return false; } }
Where Are We?Where Are We?
So far, everything is in place to read lines and So far, everything is in place to read lines and extract tokens.extract tokens.
An Exception structure is in place to report EOF.An Exception structure is in place to report EOF. The public methods so far areThe public methods so far are
– nextLine()nextLine()– nextWord()nextWord()– nextBoolean()nextBoolean()
Now some methods for numbers.Now some methods for numbers. The plan: so long as we can find something The plan: so long as we can find something
recognizable as a double, cast it to the required type.recognizable as a double, cast it to the required type.
private double nextNumber() throws RuntimeException { Double number = null; // note this is Double, not double! do { String numString = null; try { numString = nextToken(); number = new Double(numString); } catch (NumberFormatException e) { numString = numString.toLowerCase(); numString = numString.replace('d', 'e'); try { number = new Double(numString); } catch (NumberFormatException ex) { // failed again } } } while (number == null); return number.doubleValue(); }
A Little About A Little About DoubleDouble
The constructor used is The constructor used is Double(String s)Double(String s) ““Constructs a newly allocated Constructs a newly allocated DoubleDouble object that object that
represents the floating- point value of type double represents the floating- point value of type double represented by the string. The string is converted represented by the string. The string is converted to a double value as if by the to a double value as if by the valueOfvalueOf method.” method.”
See the description of See the description of valueOf()valueOf() (it’s a bit (it’s a bit complicated, but rest assured it tries hard!)complicated, but rest assured it tries hard!)
Acceptable Acceptable StringStrings include 12, -1.34, -1.0e-10, s include 12, -1.34, -1.0e-10, etc.etc.
These Two Are NaturalThese Two Are Natural
public float nextFloat() throws RuntimeException { return (float)nextNumber(); }
public double nextDouble() throws RuntimeException { return (double)nextNumber(); }
These Are Less NaturalThese Are Less Natural
public short nextShort() throws RuntimeException { return (short)nextNumber(); }
public int nextInt() throws RuntimeException { return (int)nextNumber(); }
public long nextLong() throws RuntimeException { return (long)nextNumber(); }
SimpleInputSimpleInput: Summary: Summary
Some hard design decisionsSome hard design decisions– Do everything possible to return the type asked Do everything possible to return the type asked
for.for.– Use exceptions freely to make problems visible.Use exceptions freely to make problems visible.
Are other choices possible? As always, yes!Are other choices possible? As always, yes!– Throwing exceptions from Throwing exceptions from nextInt()nextInt(), etc. seem , etc. seem
reasonable, but reasonable, but EOFEOF is a common occurrence. is a common occurrence.– Why not a hierarchy of specialized exceptions Why not a hierarchy of specialized exceptions
to make clearer just what has gone wrong?to make clearer just what has gone wrong?
Java’s Compression ClassesJava’s Compression Classes
These are used to write and read streams in These are used to write and read streams in Zip and GZIP formats.Zip and GZIP formats.
As always, these classes are wrappers As always, these classes are wrappers around existing I/O classes, for around existing I/O classes, for “transparent” use.“transparent” use.
These classes are astonishingly easy to use!These classes are astonishingly easy to use! C++ should have this…C++ should have this… Here is a picture of the input classes (the Here is a picture of the input classes (the
output classes are similar):output classes are similar):
The Compression Input ClassesThe Compression Input ClassesFilterInputStream
read():int
DataInputStream
readByte():bytereadChar():charreadDouble():doublereadInt():int
BufferedInputStream
read():int
InflatorInputStream
read():int
ZipInputStreamGZIPInputStream
CheckedInputStream
Eckel’s GZIP Example (1st part)Eckel’s GZIP Example (1st part)import java.io.*;import java.util.zip.*;public class GZIPCompress { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader( new FileReader(args[0])); BufferedOutputStream out = new BufferedOutputStream( new GZIPOutputStream(new FileOutputStream("test.gz"))); System.out.println("Writing file"); int c; while((c = in.read()) != -1) out.write(c); in.close(); out.close();
GZIP Example (2nd part)GZIP Example (2nd part)
System.out.println("Reading file"); BufferedReader in2 = new BufferedReader( new InputStreamReader( new GZIPInputStream( new FileInputStream("test.gz")))); // whew! String s; while((s = in2.readLine()) != null) System.out.println(s); }}
CommentsComments
GZIP and Zip are specific algorithms for GZIP and Zip are specific algorithms for compressing and uncompressing. You’ll compressing and uncompressing. You’ll have to wait for details until Prof. have to wait for details until Prof. McCarthy’s course.McCarthy’s course.
This program works pretty well:This program works pretty well:– DancingMen.txt is 51KBDancingMen.txt is 51KB– test.gz is 21KBtest.gz is 21KB
RTTIRTTI
We know this is possible, first, because of We know this is possible, first, because of the Cats`n`Dogs example.the Cats`n`Dogs example.
An ArrayList of Cats, with a Dog somehow An ArrayList of Cats, with a Dog somehow placed in it.placed in it.
Calling purr() for the Cats works, but not Calling purr() for the Cats works, but not for the Dog: ClassCastException.for the Dog: ClassCastException.
Second, we’ve seen this example:Second, we’ve seen this example:
Finding a BatteryFinding a Battery
boolean takeAnAABattery() { Iterator i = contents.iterator(); Object aa = null; // initialize, or compiler complains while(i.hasNext()) { if ( (aa = i.next()) instanceof AABattery ) {
contents.remove(aa); return true; } } return false; }
RTTI and PolymorphismRTTI and Polymorphismclass Shape {}class Circle extends Shape {public void draw(){}}class Square extends Shape {public void draw(){}}
public class Shapes { public static void main(String[] args) { ArrayList s = new ArrayList(); s.add(new Circle()); s.add(new Square()); Iterator e = s.iterator(); while(e.hasNext()) ((Shape)e.next()).draw(); }}
ClassClass Objects Objects
Contain information about each of the classes in Contain information about each of the classes in our program.our program.
When we write and compile a class, say When we write and compile a class, say MyClassMyClass, , the the ClassClass object for object for MyClassMyClass is generated. is generated.
When we use When we use MyClassMyClass at runtime (by creating an at runtime (by creating an object or calling a static method), the object or calling a static method), the ClassClass object object is loaded, and it creates the new is loaded, and it creates the new MyClassMyClass object. object.
The same The same ClassClass object is used to make any other object is used to make any other MyClassMyClass objects we require. objects we require.
Using Using ClassClass Objects Objects
We can get a reference to a Class object:We can get a reference to a Class object:MyClass.class;MyClass.class;
The Class class (whew!) has a number of useful The Class class (whew!) has a number of useful methods:methods:– Method[] getMethods()Method[] getMethods()– Field[] getFields()Field[] getFields()– String getName()String getName()– boolean isArray()boolean isArray()– boolean isInstance(Object)boolean isInstance(Object)– Object newInstance()Object newInstance()
newInstance()newInstance()
An alternative to the clone method we used in An alternative to the clone method we used in genetic programming.genetic programming.
ArrayList s = new ArrayList();Class[] shapes = {Circle.class, Square.class};try { for (int i = 0; i < 10; i++) { int r = Random.nextInt(2); s.add(shapes[r].newInstance()); }}catch(InstantiationException e) {throw e;}catch(IllegalAccessException e) {throw e;}
Run-Time Class InformationRun-Time Class Information
RTTI can give you the precise type of an RTTI can give you the precise type of an object at run-time, object at run-time, butbut the existence of the the existence of the type must be known type must be known at compile-timeat compile-time..
What if we get a bunch of bytes (over the What if we get a bunch of bytes (over the Web, maybe) at runtime, and we’re told Web, maybe) at runtime, and we’re told they represent a class. Can we use it?they represent a class. Can we use it?
Think of an application builder tool.Think of an application builder tool. Think of business rules in middleware on a Think of business rules in middleware on a
distant machine.distant machine.
Run-Time Class InformationRun-Time Class Information
The Class class supports “reflection”, which The Class class supports “reflection”, which is a way to get information about a class is a way to get information about a class unknown at compile-time.unknown at compile-time.
The classes Field, Method and Constructor The classes Field, Method and Constructor can be used to find this information.can be used to find this information.
These form the basis for RMI, serialization, These form the basis for RMI, serialization, JavaBeans, and javadoc.JavaBeans, and javadoc.
Too advanced for me…Too advanced for me…