Java IO系列(五):读写对象ObjectOutputStream和ObjectInputStream

转载请注明出处:http://blog.csdn.net/jeffleo/article/details/52266577

有必要多看几遍的

这里写图片描述
关于字符和字节,例如文本文件,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。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值