Java Tutorial/File/Object Serialization
Версия от 17:44, 31 мая 2010; (обсуждение)
Содержание
- 1 Class combination Serialization
- 2 Conditions for Serialization
- 3 Controlling serialization by adding your own
- 4 Deal with transient in Object Serialization
- 5 Only parent class is Serializable
- 6 Read a file of objects sequentially and displays each record
- 7 Reading an Object From a File
- 8 Saving and restoring the state of classes
- 9 Serialization Utilities
- 10 Serialization with ObjectInputStream and ObjectOutputStream
- 11 Serializing Variations on an Object
- 12 Storing Objects in a File
- 13 Writing objects sequentially to a file with class ObjectOutputStream
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
- If a superclass of your class is not serializable, it still may be possible to make your class serializable.
- Each superclass that is not serializable must have a public default constructor - a constructor with no parameters.
- Your class must implement the Serializable interface.
- Your class must serialize and deserialize the not-serializable fields in the superclasses.
- 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;
}
}