java中转换流和对象操作流

本文详细介绍了Java中的对象序列化流和反序列化流,包括使用ObjectOutputStream和ObjectInputStream进行对象的持久存储和重构。还讨论了serialVersionUID和transient关键字在对象序列化过程中的作用和应用,并提供了相关操作的实例代码。

转换流:

InputStreamReader:解码操作,字节→字符,父类是Reader

       ——构造方法 

InputStreamReader(InputStream in)使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in,String chatset)使用指定的字符编码创建InputStreamReader对象

OutputStreamWriter:编码操作,字符→字节,父类是Writer

         ——构造方法

OutputStreamWriter(OutputStream out)使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String charset)使用指定的字符编码创建OutputStreamWriter对象

对象操作流:

1、对象序列化流

What?

对象序列化流就是将对象保存到磁盘中,或者在网络中传输对象。

Why?

字节序列写到文件之后,相当于文件中持久保存了一个对象的信息。

How?

这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息。

  • 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象

ObjectOutputStream:

构造方法:

ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法:

void writeObject(Object obj)将指定的对象写入ObjectOutputStream

2、对象反序列化流

  • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象

ObjectInputStream:

构造方法:

ObjectInputStream(InputStream in)创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法:

Object readObject()从ObjectInputStream读取一个对象

3、serialVersionUID&transient【应用】

serialVersionUID

  • 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

    • 会出问题,会抛出InvalidClassException异常

  • 如果出问题了,如何解决呢?

    • 重新序列化

    • 给对象所属的类加一个serialVersionUID

      • private static final long serialVersionUID = 42L;

transient

  • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?

    • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程

4、对象操作流练习【应用】

  • 案例需求

    创建多个学生类对象写到文件中,再次读取到内存中

  • 实现步骤

    • 创建序列化流对象

    • 创建多个学生对象

    • 将学生对象添加到集合中

    • 将集合对象序列化到文件中

    • 创建反序列化流对象

    • 将文件中的对象数据,读取到内存中

  • 代码实现

    学生类

public class Student implements Serializable{
    
    private static final long serialVersionUID = 2L;

    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

测试类

public class Demo03 {
    /**
     *  read():
     *      读取到文件末尾返回值是 -1
     *  readLine():
     *      读取到文件的末尾返回值 null
     *  readObject():
     *      读取到文件的末尾 直接抛出异常
     *  如果要序列化的对象有多个,不建议直接将多个对象序列化到文件中,因为反序列化时容易出异常
     *      建议: 将要序列化的多个对象存储到集合中,然后将集合序列化到文件中
     */
    public static void main(String[] args) throws Exception {
        /*// 序列化
        //1.创建序列化流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myCode\\oos.txt"));
        ArrayList<Student> arrayList = new ArrayList<>();
        //2.创建多个学生对象
        Student s = new Student("佟丽娅",30);
        Student s01 = new Student("佟丽娅",30);
        //3.将学生对象添加到集合中
        arrayList.add(s);
        arrayList.add(s01);
        //4.将集合对象序列化到文件中
        oos.writeObject(arrayList);
        oos.close();*/

        // 反序列化
      	//5.创建反序列化流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myCode\\oos.txt"));
      	//6.将文件中的对象数据,读取到内存中
        Object obj = ois.readObject();
        ArrayList<Student> arrayList = (ArrayList<Student>)obj;
        ois.close();
        for (Student s : arrayList) {
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值