Java Tutorial/File/Object Serialization

Материал из Java эксперт
Перейти к: навигация, поиск

Class combination Serialization

   <source lang="java">

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; class ID implements Serializable { } class Employee implements Serializable {

 private String name;
 private ID myID;
 Employee(String nm, ID h) {
   name = nm;
   myID = h;
 }
 public String toString() {
   return name + "[" + super.toString() + "], " + myID + "\n";
 }

} public class MainClass {

 public static void main(String[] args) throws IOException, ClassNotFoundException {
   ID id = new ID();
   List employees = new ArrayList();
   employees.add(new Employee("A", id));
   employees.add(new Employee("B", id));
   employees.add(new Employee("C", id));
   System.out.println("employees: " + employees);
   ByteArrayOutputStream buf1 = new ByteArrayOutputStream();
   ObjectOutputStream o1 = new ObjectOutputStream(buf1);
   o1.writeObject(employees);
   o1.writeObject(employees); 
   ByteArrayOutputStream buf2 = new ByteArrayOutputStream();
   ObjectOutputStream o2 = new ObjectOutputStream(buf2);
   o2.writeObject(employees);
   ObjectInputStream in1 = new ObjectInputStream(new ByteArrayInputStream(buf1.toByteArray()));
   ObjectInputStream in2 = new ObjectInputStream(new ByteArrayInputStream(buf2.toByteArray()));
   List emp1 = (List) in1.readObject(), emp2 = (List) in1.readObject(), emp3 = (List) in2
       .readObject();
   System.out.println("emp1: " + emp1);
   System.out.println("emp2: " + emp2);
   System.out.println("emp3: " + emp3);
 }

} /*

  • /</source>



employees: [A[Employee@126b249], ID@182f0db
, B[Employee@192d342], ID@182f0db
, C[Employee@6b97fd], ID@182f0db
]
emp1: [A[Employee@750159], ID@1abab88
, B[Employee@18a7efd], ID@1abab88
, C[Employee@1971afc], ID@1abab88
]
emp2: [A[Employee@750159], ID@1abab88
, B[Employee@18a7efd], ID@1abab88
, C[Employee@1971afc], ID@1abab88
]
emp3: [A[Employee@16cd7d5], ID@cdedfd
, B[Employee@1c39a2d], ID@cdedfd
, C[Employee@bf2d5e], ID@cdedfd
]


Conditions for Serialization

  1. If a superclass of your class is not serializable, it still may be possible to make your class serializable.
  2. Each superclass that is not serializable must have a public default constructor - a constructor with no parameters.
  3. Your class must implement the Serializable interface.
  4. Your class must serialize and deserialize the not-serializable fields in the superclasses.
  5. Transient data type is not serializable.


Controlling serialization by adding your own

   <source lang="java">

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class MainClass {

 public static void main(String[] args) throws IOException, ClassNotFoundException {
   MyBean sc = new MyBean("Test1", "Test2");
   System.out.println("Before:\n" + sc);
   ByteArrayOutputStream buf = new ByteArrayOutputStream();
   ObjectOutputStream o = new ObjectOutputStream(buf);
   o.writeObject(sc);
   ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buf.toByteArray()));
   MyBean sc2 = (MyBean) in.readObject();
   System.out.println("After:\n" + sc2);
 }

} class MyBean implements Serializable {

 private String a;
 private transient String b;
 public MyBean(String aa, String bb) {
   a = "Not Transient: " + aa;
   b = "Transient: " + bb;
 }
 public String toString() {
   return a + "\n" + b;
 }
 private void writeObject(ObjectOutputStream stream) throws IOException {
   stream.defaultWriteObject();
   stream.writeObject(b);
 }
 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
   stream.defaultReadObject();
   b = (String) stream.readObject();
 }

} /*

  • /</source>



Before:
Not Transient: Test1
Transient: Test2
After:
Not Transient: Test1
Transient: Test2


Deal with transient in Object Serialization

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Date; public class MainClass {

 public static void main(String[] args) throws Exception {
   User a = new User("A", "B");
   System.out.println("logon a = " + a);
   ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("User.out"));
   o.writeObject(a);
   o.close();
   Thread.sleep(1000); // Delay for 1 second
   ObjectInputStream in = new ObjectInputStream(new FileInputStream("User.out"));
   System.out.println("Recovering object at " + new Date());
   a = (User) in.readObject();
   System.out.println("logon a = " + a);
 }

} class User implements Serializable {

 private Date date = new Date();
 private String username;
 private transient String password;
 public User(String name, String pwd) {
   username = name;
   password = pwd;
 }
 public String toString() {
   String pwd = (password == null) ? "(n/a)" : password;
   return "logon info: \n   username: " + username + "\n   date: " + date + "\n   password: "
       + pwd;
 }

}</source>





Only parent class is Serializable

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Random; abstract class Shape implements Serializable {

 public static final int RED = 1, BLUE = 2, GREEN = 3;
 private int x, y, size;
 private static Random r = new Random();
 private static int counter = 0;
 public abstract void setColor(int newColor);
 public abstract int getColor();
 public Shape(int xVal, int yVal, int dim) {
   x = xVal;
   y = yVal;
   size = dim;
 }
 public String toString() {
   return getClass() + "color[" + getColor() + "] xPos[" + x + "] yPos[" + y + "] dim[" + size
       + "]\n";
 }

} class Circle extends Shape {

 private static int color = RED;
 public Circle(int xVal, int yVal, int dim) {
   super(xVal, yVal, dim);
 }
 public void setColor(int newColor) {
   color = newColor;
 }
 public int getColor() {
   return color;
 }

} class Square extends Shape {

 private static int color;
 public Square(int xVal, int yVal, int dim) {
   super(xVal, yVal, dim);
   color = RED;
 }
 public void setColor(int newColor) {
   color = newColor;
 }
 public int getColor() {
   return color;
 }

} class Line extends Shape {

 private static int color = RED;
 public static void serializeStaticState(ObjectOutputStream os) throws IOException {
   os.writeInt(color);
 }
 public static void deserializeStaticState(ObjectInputStream os) throws IOException {
   color = os.readInt();
 }
 public Line(int xVal, int yVal, int dim) {
   super(xVal, yVal, dim);
 }
 public void setColor(int newColor) {
   color = newColor;
 }
 public int getColor() {
   return color;
 }

} public class MainClass {

 public static void main(String[] args) throws Exception {
   List shapeTypes, shapes;
   if (args.length == 0) {
     shapeTypes = new ArrayList();
     shapes = new ArrayList();
     shapeTypes.add(Circle.class);
     shapeTypes.add(Square.class);
     shapeTypes.add(Line.class);
     shapes.add(new Square(4, 3, 200));
     shapes.add(new Circle(1, 2, 100));
     shapes.add(new Line(1, 2, 100));
     ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("CADState.out"));
     out.writeObject(shapeTypes);
     Line.serializeStaticState(out);
     out.writeObject(shapes);
   } else {
     ObjectInputStream in = new ObjectInputStream(new FileInputStream(args[0]));
     shapeTypes = (List) in.readObject();
     Line.deserializeStaticState(in);
     shapes = (List) in.readObject();
   }
   System.out.println(shapes);
 }

} /*

  • /</source>



[class Squarecolor[1] xPos[4] yPos[3] dim[200]
, class Circlecolor[1] xPos[1] yPos[2] dim[100]
, class Linecolor[1] xPos[1] yPos[2] dim[100]
]


Read a file of objects sequentially and displays each record

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class MainClass {

 public static void main(String[] args) throws Exception {
   ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("clients.ser"));
   AccountRecordSerializable record;
   record = new AccountRecordSerializable(1, "firstName", "lastName", 0.1);
   output.writeObject(record);
   ObjectInputStream input = new ObjectInputStream(new FileInputStream("clients.ser"));
   record = (AccountRecordSerializable) input.readObject();
   System.out.printf("%-10d%-12s%-12s%10.2f\n", record.getAccount(), record.getFirstName(), record
       .getLastName(), record.getBalance());
   output.close();
 }

} class AccountRecordSerializable implements Serializable {

 private int account;
 private String firstName;
 private String lastName;
 private double balance;
 public AccountRecordSerializable() {
   this(0, "", "", 0.0);
 }
 public AccountRecordSerializable(int acct, String first, String last, double bal) {
   setAccount(acct);
   setFirstName(first);
   setLastName(last);
   setBalance(bal);
 }
 public void setAccount(int acct) {
   account = acct;
 }
 public int getAccount() {
   return account;
 }
 public void setFirstName(String first) {
   firstName = first;
 }
 public String getFirstName() {
   return firstName;
 }
 public void setLastName(String last) {
   lastName = last;
 }
 public String getLastName() {
   return lastName;
 }
 public void setBalance(double bal) {
   balance = bal;
 }
 public double getBalance() {
   return balance;
 }

}</source>





Reading an Object From a File

   <source lang="java">

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class MainClass {

 public static void main(String[] args) throws Exception {
   Junk obj1 = new Junk("A");
   Junk obj2 = new Junk("B");
   Junk obj3 = new Junk("V");
   ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(
       new FileOutputStream("C:/JunkObjects.bin")));
   objectOut.writeObject(obj1); // Write object
   objectOut.writeObject(obj2); // Write object
   objectOut.writeObject(obj3); // Write object
   objectOut.close(); // Close the output stream
   ObjectInputStream objectIn = null;
   int objectCount = 0;
   Junk object = null;
   objectIn = new ObjectInputStream(new BufferedInputStream(new FileInputStream(
       "C:/JunkObjects.bin")));
   // Read from the stream until we hit the end
   while (objectCount < 3) {
     object = (Junk) objectIn.readObject();
     objectCount++;
     System.out.println(object);
   }
   objectIn.close();
 }

} class Junk implements Serializable {

 String str;
 public Junk(String s) {
   str = s;
 }

}</source>





Saving and restoring the state of classes

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Random; abstract class Shape implements Serializable {

 public static final int RED = 1, BLUE = 2, GREEN = 3;
 private int x, y, size;
 private static Random r = new Random();
 private static int counter = 0;
 public abstract void setColor(int newColor);
 public abstract int getColor();
 public Shape(int xVal, int yVal, int dim) {
   x = xVal;
   y = yVal;
   size = dim;
 }
 public String toString() {
   return getClass() + "color[" + getColor() + "] xPos[" + x + "] yPos[" + y + "] dim[" + size
       + "]\n";
 }

} class Circle extends Shape {

 private static int color = RED;
 public Circle(int xVal, int yVal, int dim) {
   super(xVal, yVal, dim);
 }
 public void setColor(int newColor) {
   color = newColor;
 }
 public int getColor() {
   return color;
 }

} class Square extends Shape {

 private static int color;
 public Square(int xVal, int yVal, int dim) {
   super(xVal, yVal, dim);
   color = RED;
 }
 public void setColor(int newColor) {
   color = newColor;
 }
 public int getColor() {
   return color;
 }

} class Line extends Shape {

 private static int color = RED;
 public static void serializeStaticState(ObjectOutputStream os) throws IOException {
   os.writeInt(color);
 }
 public static void deserializeStaticState(ObjectInputStream os) throws IOException {
   color = os.readInt();
 }
 public Line(int xVal, int yVal, int dim) {
   super(xVal, yVal, dim);
 }
 public void setColor(int newColor) {
   color = newColor;
 }
 public int getColor() {
   return color;
 }

} public class MainClass {

 public static void main(String[] args) throws Exception {
   List shapeTypes, shapes;
   if (args.length == 0) {
     shapeTypes = new ArrayList();
     shapes = new ArrayList();
     shapeTypes.add(Circle.class);
     shapeTypes.add(Square.class);
     shapeTypes.add(Line.class);
     shapes.add(new Square(4, 3, 200));
     shapes.add(new Circle(1, 2, 100));
     shapes.add(new Line(1, 2, 100));
     ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("CADState.out"));
     out.writeObject(shapeTypes);
     Line.serializeStaticState(out);
     out.writeObject(shapes);
   } else {
     ObjectInputStream in = new ObjectInputStream(new FileInputStream(args[0]));
     shapeTypes = (List) in.readObject();
     Line.deserializeStaticState(in);
     shapes = (List) in.readObject();
   }
   System.out.println(shapes);
 }

} /*

  • /</source>



[class Squarecolor[1] xPos[4] yPos[3] dim[200]
, class Circlecolor[1] xPos[1] yPos[2] dim[100]
, class Linecolor[1] xPos[1] yPos[2] dim[100]
]


Serialization Utilities

   <source lang="java">

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SerializationUtils {

   public static byte[] serialize(Object obj) {
       try {
           ByteArrayOutputStream buffer = new ByteArrayOutputStream();
           ObjectOutputStream oos = new ObjectOutputStream(buffer);
           oos.writeObject(obj);
           oos.close();
           return buffer.toByteArray();
       } catch (IOException e) {
           e.printStackTrace();
           throw new RuntimeException("error writing to byte-array!");
       }
   }
   public static Object deserialize(byte[] bytes)
           throws ClassNotFoundException {
       try {
           ByteArrayInputStream input = new ByteArrayInputStream(bytes);
           ObjectInputStream ois = new ObjectInputStream(input);
           return ois.readObject();
       } catch (IOException e) {
           e.printStackTrace();
           throw new RuntimeException("error reading from byte-array!");
       }
   }
   public static Object serializedCopy(Object obj) {
       try {
           return deserialize(serialize(obj));
       } catch (ClassNotFoundException e) {
           throw new RuntimeException("this shouldn"t happen");
       }
   }

}</source>





Serialization with ObjectInputStream and ObjectOutputStream

   <source lang="java">

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; class Employee implements java.io.Serializable {

 public String name;
 public String address;
 public transient int SSN;
 public int number;
 public void mailCheck() {
   System.out.println("Mailing a check to " + name + " " + address);
 }

} class SerializeDemo {

 public static void main(String[] args) {
   Employee e = new Employee();
   e.name = "A";
   e.address = "B";
   e.SSN = 11111;
   e.number = 101;
   try {
     FileOutputStream fileOut = new FileOutputStream("employee.ser");
     ObjectOutputStream out = new ObjectOutputStream(fileOut);
     out.writeObject(e);
     out.close();
     fileOut.close();
   } catch (IOException i) {
     i.printStackTrace();
   }
 }

} class DeserializeDemo {

 public static void main(String[] args) {
   Employee e = null;
   try {
     FileInputStream fileIn = new FileInputStream("employee.ser");
     ObjectInputStream in = new ObjectInputStream(fileIn);
     e = (Employee) in.readObject();
     in.close();
     fileIn.close();
   } catch (IOException i) {
     i.printStackTrace();
     return;
   } catch (ClassNotFoundException c) {
     System.out.println("Employee class not found");
     c.printStackTrace();
     return;
   }
   System.out.println("Name: " + e.name);
   System.out.println("Address: " + e.address);
   System.out.println("SSN: " + e.SSN);
   System.out.println("Number: " + e.number);
 }

}</source>





Serializing Variations on an Object

   <source lang="java">

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class Data implements Serializable {

 private int value;
 public Data(int init) {
   value = init;
 }
 public boolean equals(Object obj) {
   if (obj instanceof Data && ((Data) obj).value == value) {
     return true;
   }
   return false;
 }
 public void setValue(int val) {
   value = val;
 }
 public int getValue() {
   return value;
 }

} public class MainClass {

 public static void main(String[] args) {
   Data data = new Data(1);
   try {
     ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(
         new FileOutputStream("C:/test.bin")));
     objectOut.writeObject(data);
     System.out.println("1st Object written has value: " + data.getValue());
     data.setValue(2);
     objectOut.writeObject(data);
     System.out.println("2nd Object written has value: " + data.getValue());
     data.setValue(3);
     objectOut.writeObject(data);
     System.out.println("3rd Object written has value: " + data.getValue());
     objectOut.close();
   } catch (IOException e) {
     e.printStackTrace(System.err);
   }
   try {
     ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream(
         new FileInputStream("C:/test.bin")));
     Data data1 = (Data) objectIn.readObject();
     Data data2 = (Data) objectIn.readObject();
     Data data3 = (Data) objectIn.readObject();
     System.out.println(data1.equals(data2));
     System.out.println(data2.equals(data3));
     System.out.println(data1.getValue());
     System.out.println(data2.getValue());
     System.out.println(data3.getValue());
     objectIn.close();
   } catch (Exception e) {
     e.printStackTrace(System.err);
   }
 }

}</source>



1st Object written has value: 1
2nd Object written has value: 2
3rd Object written has value: 3
true
true
1
1
1


Storing Objects in a File

   <source lang="java">

import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class MainClass {

 public static void main(String[] args) throws Exception {
   Junk obj1 = new Junk("A");
   Junk obj2 = new Junk("B");
   Junk obj3 = new Junk("V");
   ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(
       new FileOutputStream("C:/JunkObjects.bin")));
   objectOut.writeObject(obj1); // Write object
   objectOut.writeObject(obj2); // Write object
   objectOut.writeObject(obj3); // Write object
   System.out.println("\n\nobj1:\n" + obj1 + "\n\nobj2:\n" + obj2 + "\n\nobj3:\n" + obj3);
   objectOut.close(); // Close the output stream
 }

} class Junk implements Serializable{

 String str;
 public Junk(String s) {
   str = s;
 }

}</source>



obj1:
Junk@c2a132
obj2:
Junk@337d0f
obj3:
Junk@1e4cbc4


Writing objects sequentially to a file with class ObjectOutputStream

   <source lang="java">

import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class MainClass {

 public static void main(String[] args) throws Exception {
   ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("clients.ser"));
   AccountRecordSerializable record;
   record = new AccountRecordSerializable(1, "firstName", "lastName", 0.1);
   output.writeObject(record);
   output.close();
 }

} class AccountRecordSerializable implements Serializable {

 private int account;
 private String firstName;
 private String lastName;
 private double balance;
 public AccountRecordSerializable() {
   this(0, "", "", 0.0);
 }
 public AccountRecordSerializable(int acct, String first, String last, double bal) {
   setAccount(acct);
   setFirstName(first);
   setLastName(last);
   setBalance(bal);
 }
 public void setAccount(int acct) {
   account = acct;
 }
 public int getAccount() {
   return account;
 }
 public void setFirstName(String first) {
   firstName = first;
 }
 public String getFirstName() {
   return firstName;
 }
 public void setLastName(String last) {
   lastName = last;
 }
 public String getLastName() {
   return lastName;
 }
 public void setBalance(double bal) {
   balance = bal;
 }
 public double getBalance() {
   return balance;
 }

}</source>