410 likes | 577 Views
JAVA Programcılığı 4.1.1. Ali R+ SARAL. Ders Planı 4.1.1. Chapter 8: Understanding Streams Streams and the New I/O Capability Understanding Streams The Classes for Input and Output The Standard Streams. Streams and the New I/O Capability.
E N D
JAVA Programcılığı 4.1.1 Ali R+ SARAL
Ders Planı 4.1.1 • Chapter 8: Understanding Streams • Streams and the New I/O Capability • Understanding Streams • The Classes for Input and Output • The Standard Streams
Streams and the New I/O Capability • The package that supports stream input/output is java.io, and it is vast. • It defines over seventy classes and interfaces.
Input and Output Streams • When you write data to a stream, the stream is called an output stream. • The output stream can go to any device to which a sequence of bytes can be transferred, • such as a file on a hard disk, or a phone line connecting your system to a remote system. • You read data from an input stream. • In principle, this can be any source of serial data, but is typically a disk file, the keyboard, or a remote computer.
Input and Output Streams • The main reason for using a stream as the basis for input and output operations is • to make your program code for these operations independent of the device involved. This has two advantages. • First, you don’t have to worry about the detailed mechanics of each device. • Second, your program will work for a variety of input/output devices without any changes to the code.
Input and Output Streams • Stream input and output methods generally permit very small amounts of data, such as a single character or byte, to be written or read in a single operation. • Transferring data to or from a stream like this may be extremely inefficient, so a stream is often equipped with a buffer in memory, in which case it is called a buffered stream. • A buffer is simply a block of memory that is used to batch up the data that is transferred to or from an external device.
Binary and Character Streams • The java.io package supports two types of streams—binary streams, which contain binary data, and character streams, which contain character data. Binary streams are sometimes referred to as byte streams. • When you write data to a binary stream, the data is written to the stream as a series of bytes, exactly as it appears in memory. • Character streams are used for storing and retrieving text. You may also use character streams to read text files not written by a Java program. • All binary numeric data has to be converted to a textual representation before being written to a character stream.
The Classes for Input and Output • InputStream The base class for byte stream input operations. • OutputStream The base class for byte stream output operations.
Basic Input Stream Operations • read() This method is abstract in the InputStream class, so it has to be defined in a subclass. • read(byte[] array) This method reads bytes from the stream into successive elements of array. • read(byte[] array, int offset, int length)
Basic Input Stream Operations • BufferedInputStream Buffers input from another stream in memory to make the read operations more efficient. • DataInputStream Reads data of primitive types from a binary stream. • CheckedInputStream Reads an input stream and maintains a checksum for the data that is read to verify its integrity. • CipherInputStream Reads data from an encrypted input stream. • DigestInputStream Reads data from an input stream and updates an associated message digest. A message digest is a mechanism for combining an arbitrary amount of data from a stream into a fixed-length value that can be used to verify the integrity of the data. • InflaterInputStream Reads data from a stream that has been compressed, such as a ZIP file, for example.
Basic Input Stream Operations • LineNumberInputStream Reads data from a stream and keeps track of the current line number. The line number starts at 0 and is incremented each time a newline character is read. • ProgressMonitorInputStream Reads data from an input stream and uses a progressmonitor to monitor reading the stream. If reading the stream takes a significant amount of time, a progress dialog will be displayed offering the option to cancel the operation. This is used in window-based applications for operations that are expected to be time-consuming. • PushbackInputStream Adds the capability to return the last byte that was read back to the input stream so you can read it again.
Basic Input Stream Operations • BufferedInputStream keyboard = new BufferedInputStream(System.in);
Stream Readers and Writers • Stream readers and writers are objects that can read and write byte streams as character streams. • Reader The base class for reading a character stream • Writer The base class for writing a character stream • Finally, the reader has an abstract read() method as a member, which is declared like this: public abstract int read(char[] buf, int offset, int length) throws IOException; • This method is the reason the Reader class is abstract and has to be implemented in any concrete subclass.
Stream Readers and Writers • write(int ch) Writes the character corresponding to the low-order 2 bytes of the integer argument, ch • write(char[] buf) Writes the array of characters buf • write(char[] buf, int offset, int length) This is an abstract method that writes • length characters from buf starting at buf[offset] • write(String str) Writes the string str • write(String str, int offset, int length) Writes length characters from str starting with the character at index position offset in the string
Using Readers • InputStreamReader keyboard = new InputStreamReader(System.in); • InputStreamReader(InputStream in, Charset s) Constructs an object with in as the underlying stream. The object will use s to convert bytes to Unicode characters. • InputStreamReader(InputStream in, CharsetDecoder dec) Constructs an object that will use the charset decoder dec to transform bytes that are read from the stream in to a sequence of Unicode characters • InputStreamReader(InputStream in, String charsetName) Constructs an object that will use the charset identified in the name charsetName to convert bytes that are read from the stream in to a sequence of Unicode characters • BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
Using Writers • For example, you could combine the capabilities of a PrintWriter with a StringWriter to obtain a String object containing binary data converted to characters: StringWriter strWriter = new StringWriter(); PrintWriter writer = new PrintWriter(strWriter); • Now you can use the methods for the writer object to write to the StringBuffer object underlying the StringWriter object: double value = 2.71828; writer.println(value); • You can get the result back as a StringBuffer object from the original StringWriter object: StringBuffer str = strWriter.getBuffer();
The Standard Streams • A standard input streamthat usually corresponds to the keyboard by default. This is encapsulated by the in member of the System class and is of type InputStream. • A standard output streamthat corresponds to output on the command line. This is encapsulated by the out member of the System class and is of type PrintStream. • A standard error output streamfor error messages that usually maps to the command-line output by default. This is encapsulated by the err member of the System class and is also of type PrintStream. • You can reassign any of these to another stream within a Java application. The System class provides the static methods setIn(),setOut(), and setErr() for this purpose.
Getting Data from the Keyboard • You create a StreamTokenizer object from a stream reader object that reads data from the underlying input stream. StreamTokenizer tokenizer = new StreamTokenizer( new BufferedReader( new InputStreamReader(System.in)));
Tokenizing a Stream • Token Description • Numbers A sequence consisting of the digits 0 to 9, plus possibly a decimal point, and a + or – sign. • Strings Any sequence of characters between a pair of single quotes or a pair of double quotes. • Words Any sequence of letters or digits 0 to 9 beginning with a letter. A letter is defined as any of A to Z and a to z or \u00A0 to \u00FF. A word follows a whitespace character and is terminated by another whitespace character, or any character other than a letter or a digit. • Comments Any sequence of characters beginning with a forward slash, /, and ending with the end-of-line character. Comments are ignored and not returned by the tokenizer. • Whitespace All byte values from \u0000 to \u0020, which includes space, backspace, horizontal tab, vertical tab, line feed, form feed, and carriage return. Whitespace acts as a delimiter between tokens and is ignored (except within a quoted string).
Tokenizing a Stream int tokenType = 0; try { while((tokenType = tokenizer.nextToken()) != tokenizer.TT_EOF) { // Do something with the token... } } catch (IOException e) { e.printStackTrace(System.err); System.exit(1); }
Customizing a Stream Tokenizer • The default tokenizing mode can be modified by calling one or other of the following methods: • resetSyntax(), ordinaryChar(int ch), whitespaceChars(int low, int hi), quoteChar(int ch), …
Try It Out Creating a Formatted Input Class import java.io.StreamTokenizer; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class FormattedInput { // Method to read an int value... // Method to read a double value... // Plus methods to read various other data types... // Helper method to read the next token private int readToken() { try { ttype = tokenizer.nextToken(); return ttype; } catch (IOException e) { // Error reading in nextToken() e.printStackTrace(System.err); System.exit(1); // End the program } return 0; } // Object to tokenize input from the standard input stream private StreamTokenizer tokenizer = new StreamTokenizer( new BufferedReader( new InputStreamReader(System.in))); private int ttype; // Stores the token type code }
Try It Out Creating a Formatted Input Class // Method to read an int value public int readInt() { for (int i = 0; i < 5; i++) { if (readToken() == tokenizer.TT_NUMBER) { return (int) tokenizer.nval; // Value is numeric, so return as int } else { System.out.println(“Incorrect input: “ + tokenizer.sval + “ Re-enter an integer”); continue; // Retry the read operation } } System.out.println(“Five failures reading an int value” + “ - program terminated”); System.exit(1); // End the program return 0; } public class InvalidUserInputException extends Exception { public InvalidUserInputException() {} public InvalidUserInputException(String message) { super(message);
Try It Out Creating a Formatted Input Class public int readInt() throws InvalidUserInputException { if (readToken() != tokenizer.TT_NUMBER) { throw new InvalidUserInputException(“ readInt() failed. “ + “Input data not numeric”); } return (int) tokenizer.nval; } public int readInt() throws InvalidUserInputException { if (readToken() != tokenizer.TT_NUMBER) { throw new InvalidUserInputException(“ readInt() failed. “ + “Input data not numeric”); } if (tokenizer.nval > (double) Integer.MAX_VALUE || tokenizer.nval < (double) Integer.MIN_VALUE) { throw new InvalidUserInputException(“ readInt() failed. “ + “Input outside range of type int “); } if (tokenizer.nval != (double) (int) tokenizer.nval) { throw new InvalidUserInputException(“ readInt() failed. “ + “Input not an integer”); } return (int) tokenizer.nval; }
Try It Out Creating a Formatted Input Class public double readDouble() throws InvalidUserInputException { if (readToken() != tokenizer.TT_NUMBER) { throw new InvalidUserInputException(“ readDouble() failed. “ + “Input data not numeric”); } return tokenizer.nval; } public String readString() throws InvalidUserInputException { if (readToken() == tokenizer.TT_WORD || ttype == ‘\”’|| ttype == ‘\’’) { return tokenizer.sval; } else { throw new InvalidUserInputException(“ readString() failed. “ + “Input data is not a string”); } }
Try It Out Formatted Keyboard Input public class TestFormattedInput { public static void main(String[] args) { FormattedInput kb = new FormattedInput(); for (int i = 0; i < 5; i++) { try { System.out.print(“Enter an integer: “); System.out.println(“Integer read: “ + kb.readInt()); System.out.print(“Enter a double value: “); System.out.println(“Double value read: “ + kb.readDouble()); System.out.print(“Enter a string: “); System.out.println(“String read: “ + kb.readString()); } catch (InvalidUserInputException e) { System.out.println(“InvalidUserInputException thrown.\n”+ e.getMessage()); } } } }
Writing to the Command Line • Up to now, you have made extensive use of the println() method from the PrintStream class in your examples to output formatted information to the screen. The out object in the expression System.out.println() is of type PrintStream. • The principle difference between the two classes is that with the PrintWriter class you can control whether or not the stream buffer is flushed when the println() method is called, whereas with the PrintStream class you cannot. • Both the PrintWriter and PrintStream classes format basic data as characters. In addition to the print() and println() methods that do this, they also define the printf() method
The printf() Method • printf(String format, Object ... args) Outputs the values of the elements in args accordingto format specifications in format. An exception of type NullPointerException will be thrown if format is null. • printf(Locale loc, String format, Object ... args) This version works as the preceding version does except that the output is tailored to the locale specified by the first argument. I’ll explain java.util .Locale class type
The printf() Method • %[argument_index$][flags][width][.precision]conversion • conversion This is a single character specifying how the argument is to be presented. • The commonly used values are: • ‘d’, ‘o’, and ‘x’ apply to integer values and specify that the output representation of the value should be decimal, octal, or hexadecimal, respectively. • ‘f’, ‘g’, and ‘a’ apply to floating-point values and specify that the output representation should be decimal notation, scientific notation (with an exponent), or hexadecimal with an exponent, respectively. • ‘c’ specifies that the argument value is a character and should be displayed as such. • ‘s’ specifies that the argument is a string. • ‘b’ specifies that the argument is a boolean value, so it will be output as “true” or “false”. • ‘h’ specifies that the hashcode of the argument is to be output in hexadecimal form. • ‘n’ specifies the platform line separator so “%n” will have the same effect as “\n”.
Formatting Numerical Data int a = 5, b = 15, c = 255; double x = 27.5, y = 33.75; System.out.printf(“x = %f y = %g”, x, y); System.out.printf(“ a = %d b = %x c = %o”, a, b, c);
Specifying the Width and Precision int a = 5, b = 15, c = 255; double x = 27.5, y = 33.75; System.out.printf(“x = %15f y = %8g”, x, y); System.out.printf(“ a = %1$5d b = %2$5x c = %3$2o”, a, b, c);
Formatting Characters and Strings int count = 0; for(int ch = ‘a’ ; ch<= ‘z’ ; ch++) { System.out.printf(“ %1$4c%1$4x”, ch); if(++count%6 == 0) { System.out.printf(“%n”); } }
The Locale Class • You can pass an object of type java.util.Locale as the first argument to the printf() method, preceding the format string and the variable number of arguments that you want displayed. • The first argument specifies a language as a string of two lowercase letters representing • a Language Code defined by the standard ISO-639. Examples of language codes are “fr” for French,
Formatting Data into a String • double x = 27.5, y = 33.75; • String outString = String.format(“x = %15.2f y = %14.3g”, x, y); • StringBuffer buf = new StringBuffer(); • java.util.Formatter formatter = new java.util.Formatter(buf); • double x = 27.5, y = 33.75; • formatter.format(“x = %15.2f y = %14.3g”, x, y); • System.out.print(buf);