1 / 51

Object-Oriented Programming 95-712

Object-Oriented Programming 95-712. MISM/MSIT Carnegie Mellon University Lecture 10: I/O, RTTI. Today’s Topics. The File class Using command line arguments More on the Java I/O classes The SimpleInput class, in detail Java’s compression classes (briefly)

heaton
Download Presentation

Object-Oriented Programming 95-712

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Object-Oriented Programming95-712 MISM/MSIT Carnegie Mellon University Lecture 10: I/O, RTTI

  2. Today’s Topics • The File class • Using command line arguments • More on the Java I/O classes • The SimpleInput class, in detail • Java’s compression classes (briefly) • Run-time type identification (RTTI) • A little on javadoc

  3. The File Class • Think of this as holding a file name, or a list of file names (as in a directory). • You create one by giving the constructor a pathname, as in File f = new File(D:\Together5.02\myprojects\JavaCourse\Week9\DirList\.); • This is a directory, so now the Filef holds a list of (the names of) files in the directory. • It’s straightforward to print them out.

  4. Listing Files import 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]); } }

  5. With No Command Line Args… D:\Together5.02\myprojects\JavaCourse\Week9\DirList\. default.dfPackage default.dfPackage.wmf DirFilter.java DirList.java DirList.tpr DirList.tws

  6. With “.java” on the Command Line D:\Together5.02\myprojects\JavaCourse\Week9\DirList\. DirFilter.java DirList.java

  7. DirFilter is a FilenameFilter • Its only method is 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; } }

  8. Using the “args” in main() • All this time we’ve been dumbly typing public static void main(String[] args) {… • args is an array of Strings, but for us it’s usually been empty. • It contains any command line parameters we choose to include. • If we’re at a DOS or Unix command line, we might type >java DirList .java • In Together, we set the Run Configuration

  9. Setting the Run Configuration

  10. Other File Methods • canRead() • canWrite() • exists() • getParent() • isDirectory() • isFile() • lastModified() • length()

  11. File Methods for Modifying • createNewFile() • delete() • makeDir() • makeDirs() • renameTo() • setLastModified() • setReadOnly()

  12. More on Input All of these return bytes!

  13. FilterInputStream JavaDoc • A FilterInputStream contains some other input stream, which it uses as its basic source of data, possibly transforming the data along the way or providing additional functionality. • The class FilterInputStream itself simply overrides all methods of InputStream with versions that pass all requests to the contained input stream. • Subclasses of FilterInputStream may further override some of these methods and may also provide additional methods and fields.

  14. Readers These return chars!

  15. We 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");

  16. OutputStreams and Writers • Basically, a “mirror image” of InputStreams and Readers. • 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(); } }

  17. FileWriter • Again, basically the same. The constructors are • FileWriter(File file) • FileWriter(FileDescriptor fd) • FileWriter(String s) • FileWriter(String s, boolean append) • The last one allows appending, rather than writing to the beginning (and erasing an existing file!). • These will create files! • There is also PrintWriter

  18. PrintWriter 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

  19. The SimpleInput Class • You’ve used this class (by David Barnes) a number of times, now let’s examine it. • The idea is to make it easy to open a file, and provide methods like • short nextShort() • double nextDouble() • …all the other primitive types • String nextWord() • String nextLine() • String getDelimiters() • void setDelimiters(String) • The “file” could be System.in.

  20. SimpleInput (cont.) • This functionality is provided in C++ by the standard iostream library. Why something similar isn’t “stock” in Java mystifies me… • SimpleInput uses the StringTokenizer class • The StreamTokenizer class is similar, but with more features (and some drawbacks). • What’s a “token”? Any sequence of non-delimiter characters.

  21. StringTokenizer Example StringTokenizer st = new StringTokenizer("this is a test"); while (st.hasMoreTokens()) { println(st.nextToken()); } This prints: this is a test The default delimiter string is " \t\n\r\f"

  22. How Does It Work? Tokenizer initialized with a String: delimiters { \t\n\r\f} t h i s i s a t e s t Call nextToken(); search forward for next non-delimiter, and remember its position delimiters { \t\n\r\f} t h i s i s a t e s t (A very short search this time!)

  23. How Does It Work (cont.) Search forward for next delimiter, and remember its position delimiters { \t\n\r\f} t h i s i s a t e s t Create and return the substring between these two positions. delimiters { \t\n\r\f} t h i s i s a t e s t t h i s

  24. The Basic Plan • A StringTokenizer holds the current line. • Upon a request for a token: • if there are tokens remaining in the current line, try to convert the next token to the desired type, and return it • otherwise, skip and try to convert the next token • otherwise, read a new line, and try again • Upon a request for the next line: • discard the “left-over” line • read a new line and return it

  25. Private 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(""); }

  26. Private Variables • This illustrates the way that Java implements “default values”. • A class simply initializes member variables to default values in its class declaration, and leaves it to a constructor to change the defaults as required. • This is equivalent to the C++ technique of default constructor arguments. • There are “set `n get” methods for these:

  27. Private 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; }

  28. SimpleInput 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."); } } }

  29. getLine() (Note It’s public) 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()); } }

  30. Is EOF An Exception? • Exceptions are things we don’t expect will ever happen. • But EOF happens for every file! • Is null an OK thing to return from getLine()? • Isn’t null just what a Reader returns? • Will this cause problems elsewhere?

  31. Now 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 }

  32. 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; } }

  33. Where Are We? • So far, everything is in place to read lines and extract tokens. • An Exception structure is in place to report EOF. • The public methods so far are • nextLine() • nextWord() • nextBoolean() • Now some methods for numbers. • The plan: so long as we can find something recognizable as a double, cast it to the required type.

  34. 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(); }

  35. A Little About Double • The constructor used is Double(String s) • “Constructs a newly allocated Double object that represents the floating- point value of type double represented by the string. The string is converted to a double value as if by the valueOf method.” • See the description of valueOf() (it’s a bit complicated, but rest assured it tries hard!) • Acceptable Strings include 12, -1.34, -1.0e-10, etc.

  36. These Two Are Natural public float nextFloat() throws RuntimeException { return (float)nextNumber(); } public double nextDouble() throws RuntimeException { return (double)nextNumber(); }

  37. These 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(); }

  38. SimpleInput: Summary • Some hard design decisions • Do everything possible to return the type asked for. • Use exceptions freely to make problems visible. • Are other choices possible? As always, yes! • Throwing exceptions from nextInt(), etc. seem reasonable, but EOF is a common occurrence. • Why not a hierarchy of specialized exceptions to make clearer just what has gone wrong?

  39. Java’s Compression Classes • These are used to write and read streams in Zip and GZIP formats. • As always, these classes are wrappers around existing I/O classes, for “transparent” use. • These classes are astonishingly easy to use! • C++ should have this… • Here is a picture of the input classes (the output classes are similar):

  40. The Compression Input Classes

  41. 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();

  42. 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); } }

  43. Comments • GZIP and Zip are specific algorithms for compressing and uncompressing. You’ll have to wait for details until Prof. McCarthy’s course. • This program works pretty well: • DancingMen.txt is 51KB • test.gz is 21KB

  44. RTTI • We know this is possible, first, because of the Cats`n`Dogs example. • An ArrayList of Cats, with a Dog somehow placed in it. • Calling purr() for the Cats works, but not for the Dog: ClassCastException. • Second, we’ve seen this example:

  45. Finding 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; }

  46. RTTI and Polymorphism class 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(); } }

  47. Class Objects • Contain information about each of the classes in our program. • When we write and compile a class, say MyClass, the Class object for MyClass is generated. • When we use MyClass at runtime (by creating an object or calling a static method), the Class object is loaded, and it creates the new MyClass object. • The same Class object is used to make any other MyClass objects we require.

  48. Using Class Objects • We can get a reference to a Class object: MyClass.class; • The Class class (whew!) has a number of useful methods: • Method[] getMethods() • Field[] getFields() • String getName() • boolean isArray() • boolean isInstance(Object) • Object newInstance()

  49. newInstance() 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;} • An alternative to the clone method we used in genetic programming.

  50. Run-Time Class Information • RTTI can give you the precise type of an object at run-time, but the existence of the type must be known at compile-time. • What if we get a bunch of bytes (over the Web, maybe) at runtime, and we’re told they represent a class. Can we use it? • Think of an application builder tool. • Think of business rules in middleware on a distant machine.

More Related