1 / 42

Files, Streams and Exceptions

Files, Streams and Exceptions. The java.io.File class. Provides facilities for file manipulation File f = new File("grades.dat"); Can now use exists() canWrite() / canRead() isFile() / isDirectory() renameTo(File newName) / delete() mkdir() / list () (if directory) lastModified()

ramiro
Télécharger la présentation

Files, Streams and Exceptions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Files, Streams and Exceptions Chris Loftus

  2. The java.io.File class • Provides facilities for file manipulation File f = new File("grades.dat"); • Can now use • exists() • canWrite() / canRead() • isFile() / isDirectory() • renameTo(File newName) / delete() • mkdir() / list () (if directory) • lastModified() • length() • createNewFile()

  3. Stream Fundamentals • Streams read from a source and pass data to a sink • A stream can be a source and/or a sink • Streams build on each other

  4. Buffering Data read(byte[]) YourClass FileInputStream • One problem here is efficiency of disk accesses • Every read can potentially lead to a disk head move • Let’s see how we can improve efficiency… Bytes returned in your byte array Bytes read from disk

  5. read(byte[], …) If buffer empty, read a whole buffer worth of bytes BufferedInput Stream YourClass FileInputStream Bytes returned in your byte array Bytes returned to fill internal buffer Bytes read from disk • This solves the efficiency issue but your classes normally wish to read ints, doubles etc NOT bytes! • Let’s see how we can present a better interface for your classes to use…

  6. readInt() Read 4 bytes for int BufferedInput Stream YourClass DataInput Stream Returns an int 4 bytes returned for the int Read bytes if empty Bytes returned to fill internal buffer FileInputStream Bytes read from disk Filtering Data

  7. Categories of stream • Defined in java.io • Read and write streams • “node” streams - connected to a basic source (or sink) e.g. a file • “filter” and “buffer” streams - connected to another stream as a source (or sink) • Lots of stream classes - need to learn how they fit together

  8. Stream class hierarchy CS12420

  9. Reading data DataInputStream dis = new DataInputStream(new BufferedInputStream( new FileInputStream("data"))); int i = dis.readInt(); dis.close();

  10. Reading text • Two short cuts: • BufferedReader br= new BufferedReader(new FileReader("text")); String st = br.readLine(); br.close(); • Scanner infile = new Scanner(new InputStreamReader (new FileInputStream(“text”))); String st = infile.nextLine(); infile.close();

  11. Writing data and text • Writing data requires output streams DataOutputStream dos = new DataOuputStream(new BufferedOutputStream( new FileOutputStream(“data”))); • Writing text requires writer streams BufferedWriter bw = new BufferedWriter(new FileWriter(“text”)); • Text output also has a PrintWriter PrintWriter pw = new PrintWriter(bw); pw.println("John"); pw.close();

  12. What does this mean for you?Use an incantation and stick with it (here’s mine: loading): public void load(String fn) throws IOException { try( Scanner infile = new Scanner(new InputStreamReader(new FileInputStream(fn))); ){ int num = infile.nextInt(); infile.nextLine(); // Why? for(int i=0; i<num; i++){ String n=infile.nextLine(); String p=infile.nextLine(); Contact c = new Contact(n, p); contacts.add(c); } } } Text file looks like: 2 Fred 01970622452 Chris 01970622422 contacts is ArrayList Note if instead want to detect for end of file use hasNextLine()

  13. What does this mean for you?Saving: public void save(String fn) throws IOException { try( PrintWriter outfile = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fn))); ){ outfile.println(contacts.size()); for(Contact c: contacts){ outfile.println(c.getName()); outfile.println(c.getPhone()); } } }

  14. Reading from keyboard Use the java.util.Scanner class: publicvoid readStrings () throws IOException { String s; Scanner reader = new Scanner(System.in); do { s = reader.next(); System.out.println(“Read: “ + s); }while (!s.equals(“Q”)) // Has the user asked to quit? }

  15. Catching exceptions: Example: dealing with InputMismatchException • boolean ok=false; • do{ • try{ • System.out.println(“Enter number”); • Scanner in=new Scanner(System.in); • int input = in.nextInt(); // May throw exception • in.nextLine(); • System.out.println(“You entered “ + input); • ok = true; • } • catch(InputMismatchException e){ // ok still false • } • }while(!ok);

  16. You can define your own exceptions • To deal with ‘exceptional’ situations public class MyException extends Exception{ public MyException(String msg){ super(msg); } } • Then when one of those situations happens say throw new MyException(“message”);

  17. Beware! • You SHOULD NOT deal with NullPointerExceptions this way – they are a sign that there is a logic error. • Usually that you have done something like: Person p; …. p.methodcall(); • Without ever saying p=new Person();

  18. Exception inheritance hierarchy java.lang.Throwable You cannot catch these, e.g. VirtualMachineError java.lang.Error java.lang.Exception You are forced to catch these java.lang. RuntimeException java.io.IOException Not forced to catch these Lots of others… java.lang. NullPointerException MyException Lots of others…

  19. IO Lab

  20. REFERENCE SLIDES FOR OPTIONAL HOMEWORK

  21. Serializable • What is the matter with always using text files? • Have to save everything including structure (links to other objects) and then to recreate when loading • We can save all data and the structure using Serializable • Trouble is the file is binary

  22. Consider this design FacebookUser - facebookUserId: String + FacebookUser(userId: String) + getUserURL(): String + addPost(post: StatusPost) StatusPost - text: String - Link: String - dateOfPost: java.util.Date + StatusPost(status: String) + getText(): String + setText(text: String) + getLink(): String + setLink(theLink: String) + getDateOfPost(): Date 0..* - posts

  23. Consider the Facebook system (lots of Users, lots of Posts) • Now consider some point in time where you have 2 users, each has several posts • Draw the object diagram for that situation • How would you store that data in simple text files?

  24. OR One file: 2 Fred 3 Fred post 1 info Fred post 2 info Fred post 3 info Mary 2 Mary post 1 info Mary post 2 info Users file: 2 Fred Mary Posts file: 5 Fred post 1 info Fred post 2 info Mary post 1 info Mary post 2 info Fred post 3 info Not satisfactory! Have to relink all the data in the program

  25. Look at your object diagram • It would be great to just dump the whole system object out when we save and then reload it all at once • Complete with all the links between objects no matter how complex (e.g. users could be tagged in other posts) • We can…

  26. Serializable interface public class Person implements java.io.Serializable { … } • Serializable is a marker interface: it has no methods but is used to mark the class to give serialization mechanism permission to serialize its objects • We use special IO stream classes to serialize or deserialize

  27. This uses a different kind of stream class that handles bytes rather than characters. Efficient storage but not human readable. • public void writeToFile(String fullPathOfFile) throws IOException { • try( • ObjectOutputStream myStream = • new ObjectOutputStream( • new BufferedOutputStream( • new FileOutputStream(fullPathOfFile))); • ){ • System.out.println(“Writing to the file now…”); • myStream.writeObject(this); • } • }

  28. How to USE this method Person p; // Fill P with data p.writeToFile(“out.ser”);

  29. Typical Serialized file shown in editor: This contains the Person record with name “fred” age 41 ¬í sr Person— ËÁHr T“ I ageL namet Ljava/lang/String;xp)t fred

  30. What is actually saved • Fully qualified class name of every object • All objects’ primitive data • If attributes are object references, then those objects are also saved (go to point 1) • Each object has a unique serial version number to ensure it’s not saved twice and that versions read and written match up correctly • Not saved: Methods or static variables/constants and objects not marked as Serializable

  31. Reading is done differently p.readPerson(“out.ser”) would not work because there IS no p until we finish reading! Instead we need a method that returns a Person: P = Person.readPerson(“out.ser”); Example of using a static method…

  32. Here’s the code: public static Person readPerson(String fullPathOfFile) throws IOException { Person tempPerson = null; try( ObjectInputStream myStream = new ObjectInputStream( new BufferedInputStream( new FileInputStream(fullPathOfFile))); ){ tempPerson = (Person) myStream.readObject(); } catch(ClassNotFoundException e){ throw new IOException(“File had objects of incorrect class”); } return tempPerson; }

  33. What can go wrong? • NotSerializableException at runtime • This means that your classes, or the library classes you use, haven’t implemented Serializable • InvalidClassException at runtime • This happens if you serialize an object and then change the definition of the object’s class and then try to deserialize it. The unique serial version numbers will not match…

  34. If you change attributes then we want Java to throw this exception, otherwise we will lose data etc (bugs) • However, if we just make a small change (such as adding a method or reformatting) then we don’t care and don’t want to see the exception

  35. If it becomes a problem you will need to investigate the serialver command (serial version command) • You can generate a serialver yourself in your code: private static final long serialVersionUID = 1L; • Or on the command line: serialver Person Do this before you make the change and before serializing the object. Now when you make a minor change and deserialize Java will use the serial version number defined in the static final and no exception will be thrown • Or best of all using Eclipse…

  36. Beware of trying to serialize Scanner • If you keep your data separate from your manipulation (so the thing you are serializing does not have a private Scanner instance variable) you won’t have a Scanner in the stuff you are trying to save But if not… • You should make a Scanner transient so that the system ignores it during serialization: private transient Scanner scan;

  37. IO Lab Part Two (OPTIONAL)

  38. Saving and loading to/from XML • This is another nice way to I/O entire object graphs • Extensible Markup Language (XML) is a markup language created to structure, store, and transport data by defining a set of rules for encoding documents in a format that is both human-readable and machine-readable (wikipedia)

  39. This is the result: <?xml version=“1.0” encoding=“UTF-8”?> <java version=“1.7.0” class=“java.beans.XMLDecoder”> <object class=“PersonXML”> <void property=“age”> <int>30</int> </void> <void property=“name”> <string>Fred</string> </void> </object> </java>

  40. This is how you use it: import java.io.*; import java.beans.XMLEncoder; import java.beans.XMLDecoder; ///////// Must all have gets and sets public class PersonXML { private int age; private String name; // lots deleted public void write(String pathname) throws IOException { try( XMLEncoder encoder = new XMLEncoder( new BufferedOutputStream( new FileOutputStream(pathname))); ){ encoder.writeObject(this); } }

  41. public static PersonXML read(String pathname) throws IOException { PersonXML result = null; try( XMLDecoder decoder = new XMLDecoder( new BufferedInputStream( new FileInputStream(pathname))); ){ result = decoder.readObject(); } return result; } Class must be a bean - have gets and sets for all attributes and a default constructor

  42. IO Lab Part Three/Four (OPTIONAL)

More Related