Java's I/O Mechanisms

I. Java's I/O uses C++-like streams

    A. Two types of streams

        1. Byte streams: Handle input and output of bytes--primarily useful
	    for providing compact communication to files and between processes

	2. Character streams: Handle input and output of strings--Primarily 
	    useful for console I/O

	    a. No formatted I/O streams: Java was meant to be used with 
	        applets so output was meant to be primarily graphical. 

            b. Java provides both general formatting classes, Formatter, and
               special formatting classes, such as DecimalFormat,
	       that allow various primitive types to be formatted.
               i. The formatting classes simplify the internationalization of 
	          Java programs 

	      ii. The formatting objects will return different representations 
	          of an object depending on the region in the world where the 
		  program is executing. 

		  Example: The DecimalFormat class formats floating point 
		      numbers using decimal points in the US and using commas 
		      in Europe. 

	     iii. This type of formatting is more flexible than the hardcoded 
	              formatting that is done in C++ programs, although
		      it is also more complicated to use.

II. Built-in streams: Java provides three built-in byte streams for console
    I/O. If the designers could start over, they would probably make them
    character streams but originally Java only had byte streams. Character
    streams were added later

    A. provides console input
        1. Use a Scanner object to read from A Scanner object
        2. Need to use 2 scanner classes--one for reading lines, and one for
	   processing each line into tokens
        3. Make sure to close a scanner when done or it won't be garbage collected
        4. Import Scanner from java.util
        5. See the Scanner example code
            for additional details about the Scanner class

    B. System.out: provides console output

        1. print method prints strings to the console
	2. println method prints strings to the console and starts a
	    new line

	    Examples:  System.out.print("Hello World");
	               System.out.println("a = " + a + " and b = " + b);

        3. Note that you can concatenate strings and that
	       print/println will convert primitive types and objects to strings
	    a) all objects have a toString method that returns a string

        4. Use the format/printf method to create formatted output (they're both the same)
            a. Format string differences from C++
               i. %b : boolean and Boolean wrapper class
	       ii. %n : outputs the appropriate newline character for the platform
		(don't use \n)
	       iii. %, : outputs the appropriate thousands separator for numbers
               iv.  %s : works with Strings
 	       v. %f : works with floats and doubles, as well as wrapper classes
	       vi. %d : works with integral numbers, as well as wrapper classes
            b.    Everything else is pretty much the same

    C. System.err: writes error messages to the console

        1. has same methods as out

III. Console Class: the Console class was introduced in later versions of
     Java and combines the functionality of and System.out
    A. Provides a character stream interface (i.e., it makes it appear
	as though the input and output streams are character streams rather
	than byte streams)
    B. String readLine(): returns the next line of input, or null if EOF
    C. supports printf/format
    D. Does not always exist, in which case you must fall back to
	and System.out. It does not exist when:
	1. You redirect stdin from a file using the < operator
	2. The application is an app (in which case the application is
		expected to be a graphical interface)
	3. Using a Java VM earlier than 1.6
	4. The security for the system forbids it

IV. File I/O
    A. Import file i/o classes from
    B. File I/O throws an I/O Exception for most operations
	1) For now, put "throws IOException" after the method's parameters, so
           that the Java compiler does not complain
           Example: static public void main(String args[]) throws IOException { ... }
    C. Use a FileReader to open an input file and wrap it in a BufferedReader.
	A BufferedReader should read an entire file block and thus limit
	the number of accesses to the file system. Unbuffered reads will
	cause readLine to access the file system for each read.
	1) readLine: reads next line or returns null if EOF: if there is
            an empty last line in the file, readLine will return this
            line as an empty string (""). See the file io example for a way to handle input files that may or may
            not end with a newline character.
	2) ready: indicates eof (roughly): unfortunately this eof is
            reactive, which means that if there is an empty last line
            in the file, then ready() returns true and your code will
            read this empty last line. See the file io example for a way to handle input files that may or may
            not end with a newline character.
	3) close: closes the input stream (i.e., the file will get closed 
		even though the close is on the BufferedReader)
    D. File Output
        1) Use the following three classes to set up a file for writing
           a) Use FileWriter for opening a file for output
           b) Wrap the FileWriter object in a BufferedWriter object to optimize 
              writing to a file--BufferedWriter buffers the output
           c) Wrap the BufferedWriter object in a PrintWriter object to allow
              formatted output
	2) PrintWriter.close: closes the output stream (i.e., the file and
              BufferedWriter objects will get closed  even though the close is 
              on the PrintWriter)
    E. The File I/O example provides a
        good code example for File I/O

V. Using Java's Type Wrappers to Convert Numeric Strings

    A. In C/C++ you can use either the atoi/atof or sscanf functions to
       convert a numeric string to a numeric type

    B. In Java you use Java's type wrapper classes

       1. Each primitive type has a corresponding type wrapper class which
          allows that type to be manipulated as an object:

	  a. Double
	  b. Float
	  c. Long
	  d. Integer
	  e. Short
	  f. Byte
	  g. Boolean
	  h. Character

      2. Each type wrapper class has a constructor that takes the
         corresponding primitive type as a parameter and returns a
	 type wrapper object

	 Example: Double myDouble = new Double(6.0);

      3. Each type wrapper class contains a static parseTypeName
          (e.g., parseDouble) method that takes a String object and
	  returns a numeric value if the String's value can be converted
	  to a numeric value of the appropriate type.

	  a. The method throws a NumberFormatException if the String's value
	     cannot be converted


             String value = token.nextToken();
	     try {
	         double num = Double.parseDouble(value);
	     } catch (NumberFormatException e) {
	        System.out.println(value + " is not a number");

V. Converting a Primitive Type to a String

    A. Use the String class's valueOf method

        Example: String value = String.valueOf(10);