Java IO系列(五):读写对象ObjectOutputStream和ObjectInputStream
2016-08-21 12:01
821 查看
转载请注明出处:http://blog.csdn.net/jeffleo/article/details/52266577
关于字符和字节,例如文本文件,XML这些都是用字符流来读取和写入。而如RAR,EXE文件,图片等非文本,则用字节流来读取和写入。
读写对象,传输对象在Java中很常使用,在javaBean中就经常用到。一般来说,对象要能被对写,自身要实现特定的接口,Serializable或Externalizable接口。
结果为:
结果为:
可见,name确实没有被序列化
对于Serializable对象,对象不会调用它的构造器。但是Externalizable对象会调用它所有的默认构造器。而我们一般对对象初始化,不是在默认的构造器,这样的话,对象中的数据都没有初始化。
所以我们要在writeExternal中,写我们需要的数据,在readExternal中取我们需要的数据。
结果为:
可见,在writeExternal中,并没有写入address,因为我不需要它。所以我只读取到age和name。
有必要多看几遍的
关于字符和字节,例如文本文件,XML这些都是用字符流来读取和写入。而如RAR,EXE文件,图片等非文本,则用字节流来读取和写入。
读写对象,传输对象在Java中很常使用,在javaBean中就经常用到。一般来说,对象要能被对写,自身要实现特定的接口,Serializable或Externalizable接口。
实现Serializable接口对象的读写
实现了Serializable的对象,会被全序列化,当我们在进行序列化时,一般对象中存在我们不需要序列化的数据。但Serializable会全序列化,影响效率,一般来说,可能并不是最好的选择。class Person implements Serializable{ private int age; private String name; public Person(int age, String name){ this.age = age; this.name = name; } @Override public String toString(){ return "[age:" + age + ",name:" + name + "]"; } } public class TestObject { public static void main(String[] args) throws IOException, ClassNotFoundException { String path = "F:/io/person.txt"; ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path)); out.writeObject(new Person(20, "nick")); out.writeObject(new Person(21, "liu")); out.writeObject(new Person(22, "mike")); out.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream(path)); for (int i = 0; i < 3; i++) { System.out.println(in.readObject()); } in.close(); } }
结果为:
[age:20,name:nick] [age:21,name:liu] [age:22,name:mike]
transient使实现Serializable对象不全序列化
transient是一个关键字,配合Serializable使用,表示该数据不需要序列化。class Person implements Serializable{ private int age; private transient String name;//注意这里使用了transient public Person(int age, String name){ this.age = age; this.name = name; } @Override public String toString(){ return "[age:" + age + ",name:" + name + "]"; } } public class TestObject { public static void main(String[] args) throws IOException, ClassNotFoundException { String path = "F:/io/person.txt"; ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path)); out.writeObject(new Person(20, "nick")); out.writeObject(new Person(21, "liu")); out.writeObject(new Person(22, "mike")); out.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream(path)); for (int i = 0; i < 3; i++) { System.out.println(in.readObject()); } in.close(); } }
结果为:
[age:20,name:null] [age:21,name:null] [age:22,name:null]
可见,name确实没有被序列化
实现Externalizable接口对象的局部数据读写
实现Externalizable,则必须实现writeExternal(ObjectOutput out)和readExternal(ObjectInput in)这两个方法,而这两个方法正是关键。对于Serializable对象,对象不会调用它的构造器。但是Externalizable对象会调用它所有的默认构造器。而我们一般对对象初始化,不是在默认的构造器,这样的话,对象中的数据都没有初始化。
所以我们要在writeExternal中,写我们需要的数据,在readExternal中取我们需要的数据。
class Person implements Externalizable{ private int age; private String name; private String address; public Person(){ } public Person(int age, String name, String address){ this.age = age; this.name = name; this.address = address; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(age); out.writeObject(name); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { age = in.readInt(); name = (String) in.readObject(); } @Override public String toString(){ return "[age:" + age + ",name:" + name + ",address:" + address + "]"; } } public class TestObject { public static void main(String[] args) throws IOException, ClassNotFoundException { String path = "F:/io/person.txt"; ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path)); out.writeObject(new Person(20, "nick", "beijing")); out.writeObject(new Person(21, "liu", "guangzhou")); out.writeObject(new Person(22, "mike", "shanghai")); out.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream(path)); for (int i = 0; i < 3; i++) { System.out.println((Person) in.readObject()); } in.close(); } }
结果为:
[age:20,name:nick,address:null] [age:21,name:liu,address:null] [age:22,name:mike,address:null]
可见,在writeExternal中,并没有写入address,因为我不需要它。所以我只读取到age和name。
相关文章推荐
- java io系列05之 ObjectInputStream 和 ObjectOutputStream
- Java-IO之对象输入流输出流(ObjectInputStream和ObjectOutputStream)
- Java-IO之对象输入流输出流(ObjectInputStream和ObjectOutputStream)
- Java使用ObjectOutputStream和ObjectInputStream序列号对象报java.io.EOFException异常的解决方法
- Java IO--对象序列化Serializable、ObjectOutputStream、ObjectInputStream、transient
- 我的Java开发学习之旅------>Java使用ObjectOutputStream和ObjectInputStream序列号对象报java.io.EOFException异常的解决方法
- Java-IO之对象输入流输出流(ObjectInputStream和ObjectOutputStream)
- java语言编程IO流之对象序列化和ObjectInputStream与ObjectOutputStream
- Java对象序列化ObjectOutputStream和ObjectInputStream示例
- 黑马程序员——Java IO—字节流—ObjectInputStream和ObjectOutputStream
- 使用对象流读写对象代码笔记(ObjectInputStream ,ObjectOutputStream)
- Java的IO操作(三) - 对象的序列化、ObjectInputStream和ObjectOutputStream类
- java.io.ObjectOutputStream.putFields()和java.io.ObjectInputStream. readFields()
- Java IO之对象的序列化、ObjectInputStream和ObjectOutputStream类
- java对象流ObjectInputStream、ObjectOutputStream的使用
- Java对象序列化ObjectOutputStream和ObjectInputStream示例
- Java基础之对象的序列化(持久化)操作对象ObjectInputStream/ObjectOutputStream
- java将系列化后的对象保存在文件中,及反系列化 (ObjectInputStream,ObjectOutputStream)
- java基本I/O系列--ObjectInputStream 和 ObjectOutputStream 介绍
- JAVA IO系列----ObjectInputStream和ObjectOutputStream类