第1关:学习-Java输入输出之对象IO流之序列化一个对象
任务描述
本关任务:序列化给定 Student 对象到给定文件中,再通过反序列化把其转化为一个对象。
相关知识
之前我们学习了 InputStream(字节输入流)和 OutputStream (字节输出流),下面我们来了解一下它们的子类—ObjectInputStream (对象输入流)和 ObjectOutputStream(对象输出流)。
为什么要有对象流
有的时候,我们可能需要将内存中的对象持久化到硬盘上(序列化),或者将硬盘中的对象信息读到内存中(反序列化),这个时候我们需要使用对象流。
序列化和反序列化
序列化: 是对象转换成一个字节序列的过程,是一个写操作。 反序列化:一个字节序列转换成对象的过程 ,是一个读操作。 序列化和反序列化中对象所对应的类,必须是实现 Serializable 接口。
ObjectOutputStream(对象输出流)
ObjectOutputStream 是 OutputStream 的子类,也叫做序列化流。该流把对象转成字节数据输出到文件中保存,可实现对象的持久存储。
ObjectOutputStream 的构造方法
构造方法 | 说明 |
---|---|
ObjectOutputStream(OutputStream out) | 使用底层输出流创建 ObjectOutputStream 对象 |
构造方法示例:
public static void main(String[] args) throws IOException {
// 通过文件字节输出流创建对象输出流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("C:\\Users\\yy\\Desktop\\d.txt"));
}
ObjectOutputStream 的常用方法
下表是它的常用方法: | 方法 |说明 | | ———— | ———— | | write(byte[] w,int off,int len) | 把字节数组中偏移量从 off 开始的 len 个字节写入此输出流 | | write(byte [] b) |将字节数组写入此输出流 | | writeBooolean()、writeByte()、writeShort()、writeInt()| 将指定的基本数据类型以字节的方式写入到输出流 | | flush() | 刷新此输出流并强制写出所有缓冲的输出字节 | | writeUTF(String s) | 将字符串格式化顺序写入底层的输出流 | |writeObject(Object obj) |特有的方法,将指定的对象写入 ObjectOutputStream 流|
通过 writeObject 方法将 Hero 对象写入文件示例:
Hero 类:
import java.io.Serializable;
public class Hero implements Serializable { // 实现Serializable接口
private static final long serialVersionUID = 1L; //表示这个类当前的版本
public String name;
public float hp;
}
Test类:
public class Test {
public static void main(String[] args) throws IOException {
//创建一个Hero对象
Hero h = new Hero();
// 设置属性
h.name = "garen";
h.hp = 616;
// 准备一个文件用于保存该对象
File f =new File("C:\\Users\\yy\\Desktop\\d.txt");
try(
// 将Hero对象写入文件
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(f));){
objectOutputStream.writeObject(h);
}
}
}
执行结果:将对象写入了 d.txt 文件。
注意:Hero 类必须实现 Serializable 接口。
ObjectInputStream(对象输入流)
ObjectInputStream 是 InputStream 的子类,也叫做反序列流。该流将之前使用 ObjectOutputStream 序列化的原始数据恢复为对象,以流的方式读取对象。 ######ObjectInputStream 的构造方法
下表中是它的构造方法: | 构造方法 | 说明 | | ———— | ———— | | ObjectInputStream(InputStream in)| 使用底层输入流创建 ObjectInputStream 对象|
构造方法使用示例:
public static void main(String[] args) throws IOException {
// 通过文件字节输入流创建对象输入流对象
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("C:\\Users\\yy\\Desktop\\d.txt"));
}
ObjectInputStream 的常用方法
下表是它的常用方法: | 方法 | 说明 | | ———— | ———— | | read(byte[] r, int off, int len) | 从流中读入字节数据到缓冲区数组中指定位置,off 为数组偏移量,len 为写入长度。 | | read(byte [] b) | 从流中读入字节数据到缓冲区数组中 | | readBooolean()、readByte()、readShort()、readInt() |从输入流中读取基本数据类型 | | readUTF() | 按照格式化顺序读底层的输入流 | |readObject()|特有的方法,把对象读入 ObjectInputStream 流|
readObject 方法使用示例:
public static void main(String[] args) throws IOException, ClassNotFoundException {
try (
// 通过文件字节输入流创建对象输入流对象
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("C:\\Users\\yy\\Desktop\\d.txt"));) {
// 获取对象
System.out.print(objectInputStream.readObject());
}
}
执行结果:
com.company.Hero@58372a00
编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,序列化给定 Student 对象到给定文件中,再通过反序列化把其转化为一个对象,具体要求如下:
- 接收给定的一行字符串(如:/test/a.txt Bob 23,第一部分为给定文件路径,第二部分为 Student 对象姓名,第三部分为 Student 对象年龄);
- 给 Student 对象属性赋值,并序列化到文件中;
- 通过反序列化把文件内容转化为一个对象,并输出所有属性值。
Student 类代码如下:
import java.io.Serializable;
public class Student implements Serializable {
public String name;
public int age;
}
测试说明
平台将使用测试集运行你编写的程序代码,若全部的运行结果正确,则通关。
例: 测试输入:
/test/a.txt Bob 23
预期输出:
Bob
23
开始你的任务吧,祝你成功!
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class FileTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 接收给定的数据
Scanner scanner = new Scanner(System.in);
String filedir = scanner.next();
String name = scanner.next();
int age = scanner.nextInt();
// 请在此编写代码
/********** Begin **********/
// 创建Student对象
Student stu = new Student(name,age);
// 给对象属性赋值
File file = new File(filedir);
// 序列化对象到文件中,并通过反序列化读取文件内容,最后打印对象的所有属性
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(stu);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
System.out.print(ois.readObject());
/********** End **********/
}
}
import java.io.Serializable;
public class Student implements Serializable {
public String name;
public int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public String toString (){
return this.name+"\n"+this.age;
}
}