I/O 10-7-2013
I/O in Java I/O streams vs. Reader/Writer HW#3 due today Reading Assignment: Java tutorial on Basic I/O
public class Swimmer implements Cloneable { public Date geteventdate() { return (Date) eventdate.clone(); // note: Date must be cloneable } } Exercise: rewrite the above to use a copy constructor rather than clone to solve the problem
key ideas: Separate the classes that read and write bytes from the classes that interpret and format the data Layering: start with a stream & wrap other classes around it to add functionality consequence - networking is facilitated
package java.io (also see java.nio) text: Reader, Writer binary: InputStream, OutputStream converting from stream to text: InputStreamReader buffering: BufferedReader package java.util Scanner
InputStream OutputStream Reader Writer byte-oriented I/O (8-bit) binary data machine-readable only char-oriented I/O (16-bit) text data human-readable RandomAccess binary key idea: layered object start with a stream & wrap other classes around it to add functionality
standard input, standard output & standard error (default to console, but can be redirected to any stream) defined in the class System (which is in java.lang) public static final InputStream in; public static final PrintStream out; public static final PrintStream err
try { int b = System.in.read(); } catch (IOException e) OK for reading in a single byte of raw data, but what about numbers (int, float, ) or a line of text? Would like to use readline(), but to do this you need a buffered reader, not a Stream like System.in use InputStreamReader to convert from a Stream to a Reader then can use the method readline() in BufferedReader
public String readline() throws IOException Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed. Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached Throws: IOException - If an I/O error occurs
constructors for InputStreamReader include: InputStreamReader( InputStream in ); constructors for BufferedReader include: BufferedReader( Reader rin ); constructors for Scanner include: Scanner( InputStream source ); Scanner( File source ); Scanner( String source );
Choose one of the abstract classes Wrap functionality around it (buffers, files, compression, etc.) Format, if desired java.text package handles fonts, precision, internationalism, etc BufferedReader stdin = new BufferedReader( new InputStreamReader( System.in ) )
// Read and echo lines until EOS public static final String EOS = null; try { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String inline; while (( inline = stdin.readline())!= EOS) System.out.println(inLine); stdin.close(); } catch (IOException e)
// Read an int from standard input try { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String inline = stdin.readline(); int val = Integer.parseInt(inLine); Two potential errors System.out.println( Integer value is: + val); } catch (NumberFormatException e) { System.err.println(inLine + is not an int ); } catch (IOException e) { System.err.println( Unexpected IO error: + e); } error message written to Standard Error
Input InputStreamReader BufferedReader Output OutputStreamReader BufferedWriter PrintWriter, PrintStream FileReader StringReader DataInputStream ObjectInputStream ZipInputStream GZIPInputStream FileWriter StringWriter DataOutputStream ObjectOutputStream ZipOutputStream GZIPOutputStream
System.out.println("Hello" + new Date()); System.out is a PrintStream (OutputStream + ability to print data) doesn't throw Exceptions (can use method checkerror() to detect errors) println() method is polymorphic Object, String, int, float, char[], boolean + is polymorphic a + b can mean String concatenation or addition, depending on what a and b are
println adds the correct end-of-line characters for the target OS \r\n in Windows \n in Unix \r in Mac System.getProperty("line.separator") returns this string of end-of-line characters
// tostring revisited public class MyClass { private String myname; problem: platform-dependent public String tostring() { return "BadNewline@" + "\n" + myname; } public static void main(string[] args) { MyClass jack = new MyClass("Jack Frost"); System.out.println(jack); }
// tostring revisited public class BetterClass { private String myname; public static final String NEWLINE = System.getProperty( line.separator ); platform-independent public String tostring() { return GoodNewline@" + NEWLINE + myname; } public static void main(string[] args) { BetterClass jack = new BetterClass("Jack Frost"); System.out.println(jack); }
BufferedReader indata = new BufferedReader( new InputStreamReader(System.in) ); data source
BufferedReader indata = new BufferedReader( new FileReader( mydata.txt ) ); data source
default: current directory BufferedReader indata = new BufferedReader( new FileReader( mydata.txt )); or File filepath = new File( c:\\cs242\\ ); BufferedReader indata = new BufferedReader( new FileReader(filePath, mydata.txt )); class File is an abstract representation of file and directory pathnames (java.io.file, cf. p 452 HFJ2)
public FileReader(String filename) throws FileNotFoundException Creates a new FileReader, given the name of the file to read from. Parameters: filename - the name of the file to read from Throws: FileNotFoundException - if the named file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading.
try { BufferedReader stdin = new BufferedReader( new FileReader( mydata.txt )); Read an integer from the file mydata.txt
try { BufferedReader stdin = new BufferedReader( new FileReader( mydata.txt )); Read an integer from the file mydata.txt String inline = stdin.readline(); int val = Integer.parseInt(inLine); System.out.println( Integer value is: + val);
try { BufferedReader stdin = new BufferedReader( new FileReader( mydata.txt )); Read an integer from the file mydata.txt String inline = stdin.readline(); int val = Integer.parseInt(inLine); System.out.println( Integer value is: + val); } catch (NumberFormatException e) { System.err.println(inLine + is not an int );
try { BufferedReader stdin = new BufferedReader( new FileReader( mydata.txt )); Read an integer from the file mydata.txt String inline = stdin.readline(); int val = Integer.parseInt(inLine); System.out.println( Integer value is: + val); } catch (NumberFormatException e) { System.err.println(inLine + is not an int ); } catch (FileNotFoundException e) { System.err.println( Could not open file for reading );
Read an integer from the file mydata.txt try { BufferedReader stdin = new BufferedReader( new FileReader( mydata.txt )); String inline = stdin.readline(); int val = Integer.parseInt(inLine); System.out.println( Integer value is: + val); } catch (NumberFormatException e) { System.err.println(inLine + is not an int ); } catch (FileNotFoundException e) { System.err.println( Could not open file for reading ); } catch (IOException e) { System.err.println( Unexpected IO error: + e); }
// Read and echo lines, using BufferedReader public static final String EOS = null; try { BufferedReader stdin = new BufferedReader( new FileReader( MyData.txt )); String inline; while (( inline = stdin.readline())!= EOS) System.out.println(inLine); stdin.close(); } catch (IOException e) {
Java 1.5 introduced a new class: Scanner that makes it easy to read and parse strings and primitive types using regular expressions (class java.util.regex.pattern) constructors include: Scanner( File pathname ); Scanner( InputStream is ); Scanner( String aline );
try { Scanner scan = new Scanner( System.in ); Use Scanner to read an int from standard input int val = scan.nextint(); System.out.println( Integer value is: + val); } catch (InputMismatchException e) { System.err.println( Did not input an int ); } catch // what other exceptions?
Use Scanner to read an int from a text file try { Scanner scan = new Scanner( new File( mydata.txt ) ); int val = scan.nextint(); System.out.println( Integer value is: + val); } catch (InputMismatchException e) { System.err.println( Did not input an int ); } catch (FileNotFoundException e) { System.err.println( Couldn t open file for reading ); } catch // what other exceptions?
try { BufferedReader stdin = new BufferedReader( new FileReader( sample.txt )); String inline = stdin.readline(); int val = Integer.parseInt(inLine); System.out.println( Integer value is: + val); } catch (NumberFormatException e) { System.err.println(inLine + is not an int ); } catch (FileNotFoundException e) { System.err.println( Could not open file for reading ); } catch (IOException e) { } Read an integer from the file mydata.txt System.err.println( Unexpected IO error: + e);
try { Scanner scan = new Scanner( new File( sample.txt )); Java 1.5 Scanner class int val = scan.nextint(); System.out.println( Integer value is: + val); } catch (InputMismatchException e) { System.err.println( Next token is not an int ); } catch (FileNotFoundException e) { System.err.println( Could not open file for reading ); } catch (IOException e) { System.err.println( Unexpected IO error: + e); }
Use BufferedReader to read an int from standard input try { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String inline = stdin.readline(); int val = Integer.parseInt(inLine); System.out.println( Integer value is: + val); } catch (NumberFormatException e) { System.err.println(inLine + is not an int ); } catch (IOException e) { System.err.println( Unexpected IO error: + e); }
try { BufferedReader stdin = new BufferedReader( new FileReader( mydata.txt ) ); Use BufferedReader to read an int from a text file String inline = stdin.readline(); int val = Integer.parseInt(inLine); System.out.println( Integer value is: + val); } catch (NumberFormatException e) { System.err.println(inLine + is not an int ); } catch (FileNotFoundException e) { System.err.println( Couldn t open file for reading ); } catch (IOException e) { System.err.println( Unexpected IO error: + e); }
consider the text 1342 Unicode: 00 31 00 33 00 34 00 32 most environments use their own char encoding; e.g. windows: 31 33 34 32 Java provides conversion filters from Unicode to the char encoding used by the local OS
InputStreamReader converts an input stream containing bytes in a particular char encoding into a reader that emits Unicode chars public InputStreamReader(InputStream in, CharsetDecoder dec) OutputStreamReader is similar
The char data type is based on the original Unicode specification, which defined characters as fixed-width 16-bit entities. The Unicode Standard has since been changed to allow for characters whose representation requires more than 16 bits. For more information on Unicode 6.2.0, see www.unicode.org.
e.g. read keystrokes from console (recall that System.in is an InputStream), and convert to Unicode: A.. Z \u0041.. \u005a a.. z \u0061.. \u007a 0.. 9 \u0030.. \u0039 InputStreamReader isr = new InputStreamReader(System.in); int x = isr.read(); user types 4 what is x (in decimal)? 52 (hex 34)
See www.unicode.org/charts/ 8859_1 ISO Latin-1 (default) 8859_5 ISO Latin/Cyrillic Big4 Traditional Chinese etc. So, to open a file using one of these, you would call new InputStreamReader( new FileInputStream( mydata ), 8859_5 ) Cyrillic