360 likes | 370 Views
Java I/O. Input: information brought to program from an external source Output: information sent from program to an external destination External source or destination can be: Disk file or memory Another program (piping) Network location (URL) Information type can be:
E N D
Java I/O • Input: information brought to program from an external source • Output: information sent from program to an external destination • External source or destination can be: • Disk file or memory • Another program (piping) • Network location (URL) • Information type can be: • Primitive types or objects • Images or sounds
I/O Streams • A stream is a data structure facilitating handling of an information source for sequential access reads Source Program Stream writes Destination Program Programs read from and write to streams, and not the actual source or destination
Standard Input and Output Streams • Java provides references to the standard input stream (keyboard) and standard output stream (display) • System.in: an instance of the standard Java Platform InputStream class • System.out: an instance of the PrintStream class • InputStream and PrintStream are in the java.io package
InputStream Class An input stream provides 8-bit bytes. The InputStream class is a direct descendant of the Object class. The shaded subclasses implement data sink streams; unshaded subclasses implement processing streams.
Input Streams Used for Processing • InputStream: abstract superclass of all input stream classes • All subclasses of InputStream must implement read() method that returns one byte as an int: • FilterInputStream: designed to be extended to provide extra functionality involving the transformation (filtering) of data • SequenceInputStream: concatenates several streams into one logical stream • ObjectInputStream: reads data and objects that have been serialized to an output destination
Subclasses of FilterInputStream • DataInputStream: reads bytes that are parts of primitive types (int, double, etc.) and returns a specific value. • BufferedInputStream: buffers input bytes for efficiency • PushbackInputStream: adds the ability to ``push back'' or ``unread'' one byte • LineNumberInputStream: deprecated. Use LineNumberReader class instead
Input Streams Used on Data Sinks (all subclasses of InputStream) • FileInputStream: obtains input bytes from a file in a file system (intended for raw data, as for image files, only) • PipedInputStream: gets bytes from a piped output stream, usually from another program thread • ByteArrayInputStream: gets bytes from an internal buffer which is a byte array • StringBufferInputStream: deprecated. Use StringReader class instead
OutputStream Class An output stream outputs 8-bit bytes. The OutputStream class is a direct descendant of the Object class. The shaded subclasses implement data sink streams; unshaded subclasses implement processing streams.
Output Streams Used for Processing • OutputStream: abstract superclass of all output stream classes • All subclasses of OutputStream must implement write() method that writes one byte stored as an int: • FilterOutputStream: designed to be extended to provide extra functionality involving the transformation (filtering) of data • ObjectOutputStream: writes data and objects that have been serialized to an output destination
Subclasses of FilterOutputStream • DataOutputStream: writes primitive data types (int, double, etc.) • BufferedOutputStream: buffers output bytes for efficiency • PrintStream: converts primitive data types to string representation for printing • can be created to perform automatic flushing
Output Streams Used on Data Sinks (all subclasses of OutputStream) • FileOutputStream: sends output bytes to a file in a file system (intended for raw data, as for image files, only) • PipedOutputStream: sends bytes to a piped input stream, usually from another program thread • ByteArrayOutputStream: sends bytes to an internal buffer which is a byte array
Example: Echoing Bytes from Standard Input to Standard Output import java.io.*; public class Echo { public static void main(String[] args) throws IOException { int c; while ((c = System.in.read()) != -1) System.out.write(c); } }
Notes on the Example • Must import the I/O package, of which all the input and output stream classes are part • Since the read() method may encounter an I/O error, the main() method must either: • catch and deal with an IOException, or • throw the IOException to the calling procedure • Even though the streams read and write bytes, the internal storage is an int • The read() method returns -1 if EOF is encountered
Example Output Output is in red: 82% javac Echo.java 83% java Echo now is the time[Return] now is the time for all good men[Return] for all good men to come to the aid[Return] to come to the aid [ctl-D] 84%
Unix Redirection 84% java Echo > myfile now is the time for all good men to come to the aid [ctl-D] 85% cat myfile now is the time for all good men to come to the aid 86% java Echo < myfile > newfile 87% cat newfile now is the time forall good men to come to the aid 88%
Streams vs. Readers/Writers • The InputStream and OutputStream methods work on bytes • The Echo example notwithstanding, the stream classes are used primarily for binary data as in sound and images • In Java, characters are represented using 16-bit Unicode • To insure internationalization, programs dealing with character I/O should use descendants of the Reader and Writer classes
Readers Think of the Reader class like InputStream that has been specialized to deal with characters. Reader is a direct, abstract subclass of Object. Note similarity to the InputStream hierarchy.
Writers Think of the Writer class like OutputStream that has been specialized to deal with characters. Writer is a direct, abstract subclass of Object. Note similarity to the OutputStream hierarchy.
New Echo Class import java.io.*; public class Echo { public static void main(String[] args) throws IOException { InputStreamReader r = new InputStreamReader(System.in); OutputStreamWriter w = new OutputStreamWriter(System.out); int c; while ((c = r.read()) != -1) w.write(c); w.flush(); } }
Notes on the New Echo Class • InputStreamReader and OutputStreamWriter are built on top of InputStream and OutputStream • so their constructors require streams as arguments • Internal character storage is an int • Processing loop is exactly the same as for streams • The writer requires flushing
New Echo Example Output Output is in red: 93% java Echo now is the time[Return] for all good men[Return] to come to the aid[Return] [ctl-D] now is the time for all good men to come to the aid 94%
File Handling Example import java.io.*; public class FileCopy { public static void main(String[] args) throws IOException { FileReader r = new FileReader("infile"); FileWriter w = new FileWriter("outfile"); int c; while ((c = r.read()) != -1) w.write(c); w.flush(); } }
Notes on FileCopy • FileReader and FileWriter constructors can take file names as strings for arguments • Processing loop and flush call the same as before • This class is of limited use since the file names are hard coded
FileCopy Example Output 105% ls FileCopy.class FileCopy.java infile 106% cat infile Here is a test file to show that the FileCopy class really works. 107% java FileCopy 108% ls FileCopy.class FileCopy.java infile outfile 109% cat outfile Here is a test file to show that the FileCopy class really works. 110%
Exception Example 111% rm outfile 112% rm infile 113% ls FileCopy.class FileCopy.java 114% java FileCopy Exception in thread "main" java.io.FileNotFoundException: infile (No such file or directory) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.<init>(FileInputStream.java:103) at java.io.FileInputStream.<init>(FileInputStream.java:66) at java.io.FileReader.<init>(FileReader.java:39) at FileCopy.main(FileCopy.java:7) 115% Note: The FileNotFoundException class is a subclass of IOException. The exception generates a stack trace with line numbers of offending code.
Reading Strings • The BufferedReader class has a readLine() method for reading strings import java.io.*; public class FileCopy { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Source file name: "); String inFileName = br.readLine(); System.out.print("Destination file name: "); String outFileName = br.readLine(); FileReader r = new FileReader(inFileName); FileWriter w = new FileWriter(outFileName); int c; while ((c = r.read()) != -1) w.write(c); w.flush(); } }
Example Output 121% ls FileCopy.class FileCopy.java 122% java FileCopy Source file name: FileCopy.java Destination file name: X.java 123% ls FileCopy.class FileCopy.java X.java 124% cat X.java import java.io.*; public class FileCopy { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Source file name: "); String inFileName = br.readLine(); System.out.print("Destination file name: "); String outFileName = br.readLine(); ... } }
Reading Strings and Converting to Numbers • The java.lang package has classes Integer, Double, etc., whose instances have int, double, etc. as data members • These classes have static methods for converting strings to numbers • For example, the Integer class has a parseInt(<string>) method that returns an int given a String • Similarly, the Double class has a parseDouble(<string>) method that returns a double
Example import java.io.*; public class ConvertTest { public static void main(String[] args) throws IOException { int sum = 0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter an integer: "); String s = br.readLine(); while ( s != null ) { int num = Integer.parseInt(s); sum += num; System.out.print("Enter an integer: "); s = br.readLine(); } System.out.println("The sum is " + sum); } }
Notes on the Example • The readLine() method returns a null string if end of stream is reached • The parseInt() method must be fully qualified with its class name since the method is static • The parseInt() method might throw a NumberFormatException if its argument is not syntactically correct • Unlike an IOException, a NumberFormatException is not checked by the compiler
Example Output 136% java ConvertTest Enter an integer: 3 Enter an integer: 417 Enter an integer: 29 Enter an integer: 1234 Enter an integer: [ctl-D] The sum is 1683 137% java ConvertTest Enter an integer: 3 Enter an integer: 417 Enter an integer: trash Exception in thread "main" java.lang.NumberFormatException: trash at java.lang.Integer.parseInt(Integer.java:426) at java.lang.Integer.parseInt(Integer.java:476) at ConvertTest.main(ConvertTest.java:12) 138%
Lining Output Up in Columns import java.io.*; public class ColumnTest { public static void main(String[] args) throws IOException { int sum = 0; int[] nums = new int[10]; int i = 0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter an integer: "); String s = br.readLine(); while ( s != null ) { nums[i] = Integer.parseInt(s); sum += nums[i++]; System.out.print("Enter an integer: "); s = br.readLine(); } System.out.println("Numbers"); System.out.println("-------"); for (int j = 0; j < i; j++) System.out.println(nums[j]); System.out.println("-------"); System.out.println(sum + " total"); } }
Output 144% java ColumnTest Enter an integer: 3 Enter an integer: 417 Enter an integer: 29 Enter an integer: 1234 Enter an integer: [ctl-D] Numbers ------- 3 417 29 1234 ------- 1683 total 145%
Decimal Formatting • The java.text package has a DecimalFormat class for formatting decimals as strings • The DecimalFormat class has a format() method that takes an integer and formats it according to a pattern string given to the DecimalFormat object's constructor • The pattern string can have regular characters as well as special formatting characters • The special character ``0'' indicates a decimal digit • E.g. the pattern string `` 0000'' indicates a string with three leading blanks then an integer in 4-digit field
Decimal Formatting Example import java.io.*; import java.text.*; public class ColumnTest { public static void main(String[] args) throws IOException { int sum = 0; int[] nums = new int[10]; int i = 0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter an integer: "); String s = br.readLine(); while ( s != null ) { nums[i] = Integer.parseInt(s); sum += nums[i++]; System.out.print("Enter an integer: "); s = br.readLine(); } DecimalFormat f = new DecimalFormat(" 0000"); System.out.println("Numbers"); System.out.println("-------"); for (int j = 0; j < i; j++) System.out.println(f.format(nums[j])); System.out.println("-------"); System.out.println(f.format(sum) + " total"); } }
Decimal Formatting Example Output 144% java ColumnTest Enter an integer: 3 Enter an integer: 417 Enter an integer: 29 Enter an integer: 1234 Enter an integer: [ctl-D] Numbers ------- 0003 0417 0029 1234 ------- 1683 total 145% If you can figure out how to get the leading zeros to print as blanks, please let me know.