Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
2 jonkv@ida Streams and Readers/Writers File I/O: Two distinct but similar subsystems Binary I/O Input and Output in Java “Raw” byte‐based I/O c3 a4 c3 a4 – no change Two abstract base classes InputStream Byte‐, Character‐ and Object‐based I/O File Objects Resources Text I/O Character‐based I/O Some classes connect to byte streams with character encoding conversions UTF-8: ISO Latin-1: c3 a4 ä c3 a4 ä Two abstract base classes Reader Reading a byte / array of bytes OutputStream Reading a char / array of chars Writer Writing a byte / array of bytes Writing a char / array of chars 3 One concrete class for each source Binary I/O FileInputStream: From a file InputStream is; is = new FileInputStream("java.dat"); Text I/O FileReader: From a file Reader re; re = new FileReader("java.txt"); Which one on your system? System.getProperty("file.encoding") ByteArrayInputStream: From an array byte[] buffer = new byte[1024]; … fill the buffer … InputStream is; is = new ByteArrayInputStream(buffer); … read from the stream … No encoding specified: Use the platform’s default to convert bytes chars CharArrayReader: From an array char[] buffer = new char[1024]; … fill the buffer … Reader re; re = new CharArrayReader(buffer); … read from the stream … StringReader: From a String Streams and Readers/Writers 4 One concrete class for each destination Binary I/O FileOutputStream: To a file OutputStream os; os = new FileOutputStream("java.txt"); ByteArrayOutputStream: To an array byte[] buffer = new byte[1024]; OutputStream os; os=new ByteArrayInputStream(buffer); … Write to the stream … … Use the buffer … Text I/O FileWriter: To a file Writer wr; wr = new FileWriter("java.txt"); CharArrayWriter: To an array char[] buffer = new char[1024]; Writer wr; wr = new CharArrayWriter(buffer); … Read from the stream … … Use the buffer … StringWriter: To a StringBuffer jonkv@ida Streams and Readers/Writers jonkv@ida – Streams: Can't jump / “seek” back and forth – Very little basic functionality… for a reason! 6 jonkv@ida A simple OutputStream example: ▪ public static void main(String[] args) { OutputStream os = null; try { os = new FileOutputStream("java.txt"); os.write(3); os.write(new byte[] { 6, 7, 8 }); … } catch (IOException e) { … handle it … } finally { try { if (os != null) os.close(); } catch (IOException e) {…} } } Streams 5: Close everything! 8 jonkv@ida 5 jonkv@ida Streams 4: An OutputStream Example Opening and closing multiple streams: ▪ public static void main(String[] args) { InputStream is = null; OutputStream os = null; try { is = new FileInputStream("foo.txt"); os = new FileOutputStream("java.txt"); … } catch (IOException e) { … handle it … } finally { try { if (os != null) os.close(); } catch (IOException e) {…} try { if (is != null) is.close(); } catch (IOException e) {…} } One try/catch per file! } Declare it outside try {}… Use it inside… … and close it in finally {}! Filters 1: Introduction 7 Java I/O uses the decorator design pattern introduce additional functionality ▪ Add buffering ▪ Support other types of data ▪ … ”Basic” streams and readers/writers: ▪ Responsible for dealing with sources and destinations ▪ Only support raw bytes/chars Filters 2: How do Filters Work? Your code Filter streams and readers/writers jonkv@ida Error handling is important! Always make sure that every file is closed! Filter Stream Filter Stream Basic Stream A simple filter stream example: ▪ public class MyOutputStream { private OutputStream out; Your code public MyOutputStream(final OutputStream out) { this.out = out; } MyOutputStream public void write(byte b) { out.write(b); } public void write(byte[] b) { out.write(b); } … public void writeShort(short s) { FileOutputStream out.write((s & 0xFF00) >> 8); …or any other out.write(s & 0xFF); ”destination } … stream” } ▪ final FileOutputStream fos = new FileOutputStream("foo.txt"); final MyOutputStream mos = new MyOutputStream(fos); Useful output filters 10 jonkv@ida Filters 4: Output 12 jonkv@ida 9 jonkv@ida Filters 3: Output Useful output filters Binary I/O Text I/O Buffers I/O: Don't write a single byte at a time… PrintStream (System.out / err) print(), println() methods for primitive datatypes and Strings Uses platform character encoding to convert chars bytes DataOutputStream writeLong(), writeFloat(), … writeUTF() – writes UTF‐8 format writeBytes(String str) – deprecated! Ignores character encodings 11 Useful input filters Binary I/O Buffers I/O: Don't read a single byte at a time… Buffers I/O: Don't write a single char at a time… PrintWriter print(), println() methods for primitive datatypes and Strings Sufficient to close the "outer" stream: This closes all its inner streams too Filters 5: Input BufferedInputStream BufferedWriter DataOutputStream os = null; try { os = new DataOutputStream( new BufferedOutputStream( new FileOutputStream("java.txt"))); os.write(new byte[] { 6, 7, 8 }); os.writeLong(1234567890123L); os.writeFloat(2.7f); } catch (final IOException e) { … handle it … } finally { try { if (os != null) os.close(); } catch (IOException e) {…} } jonkv@ida BufferedOutputStream Filters 6: Specifying Encodings Specify a character encoding using OSW and ISR Text I/O BufferedReader Buffers I/O: Don't read a single char at a time… Method for reading a line OutputStreamWriter OutputStream os = new FileOutputStream("file.txt"); Writer wr = new OutputStreamWriter(os, “Big5"); InputStreamReader Socket sock = …; InputStream is = sock.getInputStream(); Reader re = new InputStreamReader(is, “Cp1046”); DataInputStream readLong(), readFloat(), … readUTF() – reads UTF‐8 format readLine() – deprecated! Ignores character encodings Use Readers instead! Your code Unicode chars OutputStreamWriter Bytes in Big5 encoding (Traditional Chinese) FileOutputStream Your code Unicode chars InputStreamReader Bytes in Cp1046 encoding (IBM arabic) ”SocketInputStream” 14 jonkv@ida Serialization 1: Intro Serialization: Convert objects to/from sequences of bytes OutputStream os = new FileOutputStream("file.txt"); ObjectOutputStream out = new ObjectOutputStream(os); Writes an out.writeObject(gameBoard); object and out.writeObject(highscoreList); everything out.close(); it refers to! Your code ObjectInputStream Socket sock = …; InputStream is = sock.getInputStream(); ObjectInputStream in = new ObjectInputStream(is); List<Score> highscoreList = (List<Score>) in.readObject(); in.close(); Your code Objects Objects ObjectOutputStream ObjectInputStream Bytes: All you need to reconstruct the objects Serialization 2: Serializable Interface 15 The objects must implement java.io.Serializable An interface without methods, indicating that serialization is allowed ▪ By accessing the byte stream you can read private fields! ▪ public class Pair implements Serializable { private Object first; All fields must also be Serializable! private Object second; private transient int hashCodeCache; …except transient fields, which Pair(Object first, Object second) { this.first = first; this.second = second; } we assume can be reconstructed or are unnecessary for other reasons } The superclass must: ▪ Be Serializable, so we can save its data to the stream, or ▪ Have a no‐args constructor, so we can reconstruct it from scratch Many Java classes already implement Serializable ▪ Strings, Collections subclasses, … jonkv@ida FileOutputStream Bytes ”SocketInputStream” Serialization 3: Writing An Object Twice ObjectOutputStream must handle circular references Node structure example: ▪ Node parent = new Node(null); Node child = new Node(parent); // child points to parent parent.addChild(node); // parent points to child Remembers which objects were written ▪ First time: Write object ID + entire object representation ▪ Second time: Write object ID Does not care whether the object was updated! ▪ List list = new ArrayList(); oos.write(list); // Writes object ID + entire list list.add("Another element"); oos.write(list); // Writes the object ID… To write a new copy of the object: Use reset() ▪ oos.reset(); 16 jonkv@ida ObjectOutputStream Can old saved objects be read after changing the class? Error handling was omitted ▪ ▪ ▪ ▪ ▪ ▪ Some changes are allowed ▪ Adding fields – if you read an old object, the field will be set to 0/null ▪ Changing public/protected/private ▪ A few more types of changes Others are forbidden ▪ Changing the class hierarchy in certain ways ▪ Removing Serializable ▪ … 18 jonkv@ida Serialization 5: Exceptions ClassNotFoundException InvalidClassException StreamCorruptedException OptionalDataException NotSerializableException IOException – received an object of a non‐existing class – bad control information in the stream – primitive data found instead of objects – an object was not Serializable – the usual Input/Output related exceptions Many more serialization features… ▪ http://docs.oracle.com/javase/7/docs/technotes/guides/serialization/index.html You must have the same serial version ID ▪ By default this is a hash of certain features in the class — too strict! ▪ To allow adding new fields, declare your own version ID: private final static long serialVersionUID = 1; // for example ▪ IMPORTANT! Change this if you make incompatible changes to your class! File[name] Objects: The File Class 20 File Objects (java.io.File) represent file and path names They do not represent open files! Also file system operations: ▪ File f = new File("/"); Find available space, total space, File f2 = new File(f, "etc"); file system roots (C:\, D:\), File f3 = new File(f, "passwd"); System.out.print(f3.getAbsolutePath()); if (f3.exists()) { System.out.println("You have a password file"); System.out.println("It's in the directory " + f3.getParent()); System.out.println("Its length is " + f3.length()); if (f3.canRead()) System.out.println("I can read it"); if (f3.canWrite()) System.out.println("I can write to it"); if (f3.isHidden()) System.out.println("It is hidden"); if (f3.delete()) System.out.println("I have deleted it!"); OutputStream os = new FileOutputStream(f3); } File.createNewFile() is used for atomic locking – just use a FileOutputStream in most cases! Also directory operations: listFiles(), mkdir(), renameTo(), … jonkv@ida 17 jonkv@ida Serialization 4: Class Versions Support for compression Package java.util.zip — zip, gzip, checksums Package java.util.jar — JAR archives Advanced high‐performance I/O operations Package java.nio JavaBeans Activation Framework (JAF) Given some data (a binary file), identify its type (for example, "JPEG image") Identify operations available for that type 21 jonkv@ida See Also