![]() |
A8. The Java File I/O Classes
Note: This section is provided for information only and will not be presented as part of the course lectures. In this section, you will learn:
IntroductionThe Java language provides a set of predefined classes and objects for reading and writing data to and from files on a local file system. (Recall, however, that browsers generally prohibit applet file I/O for security reasons.) Both sequential and random access are possible. In this section, we will focus on the important I/O classes providing motivation for their existence, providing examples illustrating their common use, and describing their relationship to other I/O classes.Predefined System I/O ObjectsThe Java language provides two static objects in class System for sending output to stdout and stderr:static PrintStream out; static PrintStream err;Methods print() and println() are used to print ASCII text representations of their arguments (PrintStreams chop off the high byte when it prints. To print UNICODE, you need a PrintWriter instance. For example, System.out.println("Goes to stdout with newline"); System.out.print("Goes to stdout without newline"); System.err.println("Goes to stderr with newline");The Java language also provides a static object in class System for reading input from stdin: static InputStream in;which is actually initialized to a BufferedInputStream. Method read() reads in a single character and returns -1 upon end of input: int c; try { c = System.in.read(); } catch (IOException e) {} File ObjectsYou can use File objects to obtain information about a file or directory. File objects differ from stream objects such as InputStream in that a File object is used to obtain information about a particular file or directory and is not used to read or write data. For example, to determine the length of a file:String fileName = "data"; File f = new File(fileName); System.out.println("file " + fileName + " is " + f.length() + " bytes long");For another example, when the File object is associated with a file system directory, you can easily obtain the list of files in that directory: String fileName = "examples"; File f = new File(fileName); String[] dirListing = f.list(); Writing OutputThe Java language provides class FileOutputStream for writing bytes, class FileWriter for writing characters, class DataOutputStream for writing primitive types, and classes PrintStream and PrintWriter for printing primitive types. FileOutputStream is a pure byte stream, FileWriter is a pure 16-bit char stream, DataOutputStream writes items of primitive type in binary form, and PrintStream and PrintWriter print items in human-readable form (i.e., ASCII or UNICODE, not binary). These classes are the most commonly used, and all are created either from a String filename or from a File object.The following table summarizes the file output classes we will describe:
Summary of OutputStream/Writer Hierarchy
What is class FilterOutputStream for?Because class FileOutputStream writes only bytes, the Java language provides the abstract class FilterOutputStream to enable you to write more complex types of output. The "filters" DataOutputStream and BufferedOutputStream, for example, can be chained and attached to a FileOutputStream to provide this enhanced output functionality.
These Java filters are analogous to UNIX shell pipe filters.
You might think of the Java process of attaching
DataOutputStream to FileOutputStream as being
represented in UNIX by:
FileOutputStream/FileWriterFileOutputStream is the class to use if you want to write binary bytes, FileWriter is for chars. For example, the following code writes a byte array to a file called "junk".byte[] someBytes = { 'a', 'b', 'c' }; FileOutputStream f; f = new FileOutputStream("junk"); if ( f!=null ) { f.write(someBytes); f.close(); // free up system resource } DataOutputStreamBy chaining the DataOutputStream to the FileOutputStream, you can write output that is more complex than bytes. If you have a primitive type, for example, that you want to write in binary in a portable manner, you can attach a DataOutputStream object to a FileOutputStream like this:// write 34 in binary to a file called "junk" // make a generic output byte stream FileOutputStream f = new FileOutputStream("junk"); // attach a DataOutputStream to it DataOutputStream df = new DataOutputStream(f); if ( df!=null ) { df.writeInt(34); df.close(); // free-up system resource. f.close(); // close in reverse order }The output may be portably read by DataInputStream. PrintStream/PrintWriterIf you want to print to a text file, you can use a PrintStream object. For example:FileWriter f = new FileWriter("junk"); PrintWriter pf = new PrintWriter(f); if ( pf!=null ) { pf.println(34); pf.println("an int is " + 34); pf.println(3.14159); pf.println("This is a string"); pf.close(); // free up system resource. f.close(); // close in reverse order } BufferedOutputStreamClass BufferedOutputStream allows you to write bytes to a buffer without always doing an actual file system write. The buffer is written to the stream when the buffer is full, when you close() the stream, or when you manually flush() the buffer. You must attach a BufferedOutputStream object to an OutputStream object, and you can then use it like the OutputStream object.// make a generic output byte stream f = new FileOutputStream("junk"); // attach BufferedOutputStream bf = new BufferedOutputStream(f); bf.write(34); Reading InputThe Java language provides class FileInputStream for reading bytes, FileReader for reading characters, and class DataInputStream for reading primitive types. These classes are the most commonly used and are created from either a String filename or from a File object.To read text items and convert them to primitive types, You will normally read characters into a String and then parse the String with methods such as Integer.parseInt() and Float.valueOf(). (Class StreamTokenizer is an alternative.) FilterInputStream is an abstract class for Java input, with a role analogous to FilterOutputStream of output. The following table summarizes the file input classes we will describe:
Summary of InputStream Hierarchy
FileInputStream/FileReaderUse FileInputStream if you want to read bytes from a stream. For example,// read a single byte followed by a byte array // from a file called "junk" byte[] buffer = new byte[1024]; FileInputStream f; f = new FileInputStream("junk"); if ( f!=null ) { f.read(); f.read(buffer); // reads up to 1024 bytes f.close(); // free up system resource }The different Reader classes work in the same manner but work on the character-level, instead of the byte level. If you are working with text, you should use the Reader objects, if you are using Java 1.1. DataInputStreamIf you want to read items of primitive type, portably stored in binary, use class DataInputStream. For example,int i; FileInputStream f = new FileInputStream("junk"); DataInputStream df = new DataInputStream(f); i = df.readInt(); df.close(); // close and free up system resource. f.close(); // close in reverse order StringBufferInputStreamUse class StringBufferInputStream when you want to read input from a String rather than from the file system. For example,// Read single byte followed by byte array from // string. The string has ASCII characters in it, // but the chars are read as binary bytes. String junk = "abc34def"; byte[] buffer = new byte[1024]; StringBufferInputStream f = new StringBufferInputStream(junk); byte b = f.read(); // read a byte f.read(buffer); // buffer will be {`b','c','3','4','d','e','f'} f.close(); Random Access I/OYou often want to read or write data at random positions within a file, rather than sequentially as you would with a magnetic tape. The Java RandomAccessFile class behaves like a combined DataOutputStream and DataInputStream. RandomAccessFile implements both the DataOutput and DataInput interfaces. RandomAccessFile objects are created from a String filename or File object like other stream objects, but a mode constructor argument is also required. The mode is either String "r" (read only) or "rw" (read/write), just like fopen() in C or C++.
For example,
Reading From Remote File SystemsYou can do reads and writes for files on remote file systems by using sockets. Reads can also be done via URL objects. You can ask a URL object for an InputStream from which to read. For example,try { InputStream in; byte[] buffer = new byte[100]; URL url = new URL("http://www.MageLang.com/index.html"); in = url.openStream(); DataInputStream df = new DataInputStream(in); System.out.println(df.readLine()); df.close(); } catch (Exception e) { System.out.println(e.getMessage()); }
Magercises1. Streams of primitive elements.
|
Copyright © 1996-1997 MageLang Institute. All Rights Reserved. |