java以对象流的方式存入文件_序列化流 把对象以指定的格式写入到文件中保存和读取...

序列化流

java提供了一种对象序列化的机制,用一个字节序列可以表示一个对象,该字节序列包含该对象的数据,对象的类型和对象中存储的属性等信息,字节序列写入到文件中后,就相当于在文件中保存了文件对象信息.

反之,该字节序列还可以从文件中读取出来,重构对象.对他进行反序列化.对象的数据,对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象,

ObjectOutputStream类

java.io.ObjectOutputStream类,将java对象的原始数据类型写入到文件中,实现对象的持久化存储.

构造方法

public ObjectPutputStream(OutputStream out):创建一个指定的OutputStream的的ObjectOutputStream类对象

独有的方法

void writeObject(Object obj):将指定的对象写入到对象序列化中

备注:

当某个类对象需要进行序列化时,没有实现序列化接口时会抛出该java.io.NotSerializableException 序列化异常解决:让该类实现Serializable接口,启用序列化功能,为实现此接口的类将无法使其任何状态序列化或者进行反序列化.java.io.Serializable接口,此接口内部什么也没有,这类接口也可称为标记性接口.要进行序列化和反序列化的时候,给该类添加一个标记,实现序列化接口,此时该类就有标记了.当程序要进行序列化和反序列化的时候,首先会检测该类是否有序列化标记.有:就可以进行序列化和反序列化没有:就会抛出java.io.NotSerializableException就好比大家上超市买产品,需要看产品上的生产日期

序列化操作

1.一个对象想要能够序列化和反序列化,必须满足两个条件:

该类必须实现java.io.Serializable接口,Serializable接口是一个标记性接口,如果该类没有实现Serializable接口,将会抛出NotSerializableException.

该类的所有属性必须是可以实现序列化或者反序列化,如果有一个属性不想让他参与序列化,则该属性必须标明是 瞬态的,瞬时的,这个关键字是transient,被他修饰的成员变量是没有值的.为默认值.

public class Student implements Serializable{

private String name;

private  transient  int age;//让age属性不参与序列化

ObjectinputStream类

ObjectInputStream类是反序列化流,将之前使用ObjectOutputStream序列化流的原始数据恢复为对象.

构造方法

public ObjectunputStream(inmputStream in):创建一个指定的inputStream的对象反序列化流对象.

特有的方法:

public final Object readObject():从反序列化流中读取对象

做好了一个类继承了可序列化标记好,虚拟机可以给它一个序列号.序列化存储对象文件之后,更改了类源代码,那么这个类会更新另一个序列号,那么对象文件在反序列化的时候就会报错.

所以我们面对类的序列号进行锁定,自定义一个

//可以手动自定义一个序列化版本号

private static final long serialVersionUID=1L;

锁定了序列号之后,对类进行了修改,那么反编译会通过,但是他会属性对照,类中此时还在的属性才会被抓取,而类中新增的成员变量此时不存在.

对于JVM来说,能够进行反序列的对象,前提条件是必须能够找到class文件的类,如果找不到该类的class文件,则会跑出一个ClassNotFoundException异常.

另外,当JVM序列化对象时,能找找到class文件,但是class文件再序列化对象时,发生了修改,那么反序列化操作会抛出invalidClassException异常.原因如下:

该类的序列化版本号与从流中读取出来描述该类的版本号不一致.

该类包含了位置数据类型.

该类没有可访问的无参构造方法.

Serializable接口给需要序列化的类,提供了一个序列化版本号,seriaIVersionUID改版本号的目的就在于验证序列化的对象和对应的类是否是版本一致.

//可以手动自定义一个序列化版本号

private static final long serialVersionUID=11231L;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我明白了。以下是将2个学生信息存入 students.txt 文件,并使用 Stream 遍历学号信息的 Java 代码: ``` import java.io.*; import java.util.Arrays; public class Student { private String id; private String name; private int age; public Student(String id, String name, int age) { this.id = id; this.name = name; this.age = age; } public String getId() { return id; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "Student{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age=" + age + '}'; } public static void main(String[] args) throws IOException { // 创建学生对象 Student student1 = new Student("001", "张三", 18); Student student2 = new Student("002", "李四", 20); // 将学生信息写入文件 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students.txt")); oos.writeObject(student1); oos.writeObject(student2); oos.close(); // 读取文件的学生信息,并使用 Stream 遍历所有学生的学号信息 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students.txt")); Student[] students = new Student[2]; for (int i = 0; i < 2; i++) { try { students[i] = (Student) ois.readObject(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } Arrays.stream(students).map(Student::getId).forEach(System.out::println); ois.close(); } } ``` 这段代码,我们首先创建了一个 `Student` 类,包含了学号、姓名和年龄信息。然后通过 `ObjectOutputStream` 将两个学生对象写入到 `students.txt` 文件,接着通过 `ObjectInputStream` 读取文件的学生信息,并通过 Stream 遍历所有学生的学号信息并输出。注意,在 `ObjectOutputStream` 和 `ObjectInputStream` 创建时,它们会自动创建一个序列和反序列,所以我们不需要再额外创建序列

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值