Java Tutorial/File/Object Serialization

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

Class combination Serialization

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);
  }
}
/*
*/



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

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();
  }
}
/*
*/



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


Deal with transient in Object Serialization

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;
  }
}





Only parent class is Serializable

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);
  }
}
/*
*/



[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

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;
  }
}





Reading an Object From a File

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;
  }
}





Saving and restoring the state of classes

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);
  }
}
/*
*/



[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

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");
        }
    }
}





Serialization with ObjectInputStream and ObjectOutputStream

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);
  }
}





Serializing Variations on an Object

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);
    }
  }
}



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

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;
  }
}



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


Writing objects sequentially to a file with class ObjectOutputStream

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;
  }
}