Java I/O The Cheat Sheet Reading and Writing • The basic architecture of Java IO is pluggable. The idea is to have some very simple classes do very simple IO, and then use those simple classes in a variety of other classes that are much more capable • The InputStream and OutputStream are the very simple building blocks • Things like PrintWriter are the more capable classes Packages • The IO classes are in the java.io package • Use import java.io.* to get them all • http://download.oracle.com/docs/cd/E17409 _01/javase/6/docs/api/ for documentation OutputStream • The OutputStream class knows how to write an array of bytes and a single byte. That’s it. That makes it pretty easy to write for a lot of contexts • A FileOutputStream writes to a file on disk • A ByteArrayOutputStream writes to a chunk of memory Complex Output • We probably want to do more than just write byte arrays. For example, we probably want to write – – – – – Strings Floating point numbers in binary format Booleans Characters Integers • These are all handled by classes that make use of OutputStreams, but are not OutputStreams PrintWriter • Suppose we want to output text. We can create a PrintWriter object, and place some instance of an OutputStream in it via the constructor. PrintWriter knows how to convert strings to what the OutputStream understands PrintWriter The PrintWriter API has printDouble, println, etc, and talks to the OutputStream API, which only understands writing byte arrays Depending on what sort of OutputStream This is, it may write to a file, memory, Etc. PrintWriter OutputStream Example • Create a PrintWriter that writes to a file FileOutputStream fos = new FileOutputStream(“foo.txt”); PrintWriter pw = new PrintWriter(fos); pw.println(“Hello world”); pw.flush(); pw.close(); This creates a FileOutputStream that points to a file on disk named foo.txt. The PrintWriter instance contains the FileOutputStream instance, and we use the PrintWriter API to write a string to the file Example • Create a PrintWriter that sends output to a socket Socket aSocket = new Socket(anInetAddress, port); OutputStream os = aSocket.getOutputStream(); PrintWriter pw = new PrintWriter(os); pw.println(“Hello world”); pw.flush(); pw.close(); This creates a socket that is connected to an IP address And port. The OutputStream in the socket is retrieved, And used to create a PrintWriter instance. We can use The exact same PrintWriter API to send data to a host As we do to write to a file! Example • Create a PrintWriter that writes to a memory buffer ByteArrayOutputStream os = new ByteArrayOutputStream(); PrintWriter pw = new PrintWriter(os); pw.println(“Hello world”); pw.flush(); pw.close(); This creates a ByteArrayOutputStream, which sends output to a memory buffer. Again, the same PrintWriter API can be used as the other two examples Flush? • For performance reasons, when you do a println() the data may not actually be written to the underlying output stream right away • You can call flush() at any time to force any data lounging around to be written through • This is important in network programming! Always remember to flush() if you hope to see the data actually be sent across the wire Close? • The call to close() is your way of telling the operating system “I will never write anything to this stream ever again” and the operating system can reclaim any resources associated with the stream Print vs. Println • Println adds a carriage return character after the data to be written • This is important for “data framing” in network programming; you need to know when one line of data ends an anther begins • The carriage return or newline character is very often used to say “this is the end of a line of data” InputStreams • A very similar process is used for input streams. InputStreams are very simple, but we can use InputStreams in other objects that provide a nice API Other Than Text • Notice that the PrintWriter outputs Strings, not a binary representation of things like floating point numbers. • We can use other classes if we want to write binary data to an output stream instead of string data DataOutputStream • Often used for writing binary data FileOutputStream fos = new FileOutputStream(“foo.txt”); DataOutputStream dos = new DataOutputStream(fos); dos.writeFloat(17.0); dos.writeDouble(23.0); dos.flush(); dos.close(); DataOutputStream • What if you wanted to create a memory buffer that had two floating point numbers in it, in binary format? ByteArrayOutputStream os = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(os); dos.writeFloat(17.0); dos.writeFloat(23.0); byte data[] = dos.toByteArray(); Reading & Writing Objects • Java has a very slick ability to read and write entire object instances to an IO stream, provided the class implements something called the Serializable interface • For the most part, just make sure the class, and any objects it contains, implement the interface, which has no methods • Exactly the same class needs to exist on the reading side • Doesn’t work outside of Java Reading & Writing Objects • Class implements Serializable: public class MyClass implements Serializable { int x; int y; public int getX(); } Writing Object Instances FileOutputStream fos = new FileOutputStream(“foo.tmp”); ObjectOutputStream oos = new ObjectOutputStream(fos); MyClass anObjectInstance = new MyClass(); oos.writeObject(anObjectInstance); oos.close(); Reading Object Instances FileInputStream fis = new FileInputStream(“foo.tmp”); ObjectInputStream ois = new ObjectOutputStream(fis); MyClass anObjectInstance ; anObjectInstance = ois.ReadObject(); ois.close(); Cheat Sheet: Text IO • Use when you want to write string representations PrintWriter pw = new PrintWriter(yourOutputStream); pw.println(“some data”); pw.writeDouble(17.0); pw.flush(); pw.close(); Cheat Sheet: Reading Text • Use when you want to read text data from an input stream BufferedReader br = new BufferedReader( new InputStreamReader(yourInputStream)); String someText = br.readln(); Cheat Sheet: Writing Binary • Write binary data to a memory buffer ByteArrayOutputStream os = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(os); dos.writeFloat(17.0); dos.writeFloat(23.0); byte data[] = dos.toByteArray(); Cheat Sheet: Reading Binary • Read binary data from a memory buffer ByteArrayInputStream bais = new ByteArrayInputStream(anArrayOfBytes); DataInputStream dis = new DataInputStream(bais); dis.readFloat(); dis.readDouble(); Java IO • It’s not that bad if you don’t panic