1

Java序列化流的奇妙之旅

 2 years ago
source link: https://blog.51cto.com/u_12039705/5088820
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Java序列化流有何奇妙之处呢?通过一个个案例逐一感受序列化流。

!!!好戏在后头!!!

​1.IO流读写文件​

先从一个普通文件读写字符串开始讲起。

例子:输出字符串到文件,再从文件中读取字符串

Java序列化流的奇妙之旅_序列化

在某一天灵感迸发:我可以把Java程序中的对象信息直接保存到普通的 txt 文件中吗?并且当我想使用它时,还可以拿出来就可以直接用,不需要再做其他处理,就像存储普通的字符串一样,在文件中读出来就可以直接使用的那种。

​2.序列化和反序列化流奇妙之处​

要想实现对象信息存储到普通文件不被破化,并且读取出来不需要再做其他处理既可以像使用普通new出来的对象一样直接使用的效果,必须有一种特殊的IO流来完成,于是诞生了序列化流和反序列化流

2.1.案例一:把普通文件当作对象存储库来使用

详细的描述:将一个list 集合保存到普通文件,再读出来直接使用,实现list集合数据的增删改查

Person 类

// 序列化对象信息:必须实现序列化标记接口Serializable
public class Person implements Serializable {
// 序列化版本UID
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String sex;
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}

@Override
public String toString() {
return "Person{" + "name='" + name + ", age=" + age + ", sex='" + sex + '}';
}
public Person() {
}
public Person(String name, Integer age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}

序列化和反序列化

public class Demo2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//数据准备:集合类都实现了序列化接口Serializable
List<Person> list = new ArrayList<>();
list.add(new Person("张三",38,"男"));
list.add(new Person("李四",38,"男"));
list.add(new Person("如花",18,"女"));

// 序列化保存到普通文件
File file = new File("D:/demo2.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(list);
objectOutputStream.close();

// 读取普通文件反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
List<Person> personList = (List<Person>) objectInputStream.readObject();
objectInputStream.close();
for (Person person:personList){
System.out.println(person);
}

}
}

执行结果:

Java序列化流的奇妙之旅_java_02

序列化保存到普通文件的数据:

Java序列化流的奇妙之旅_序列化_03

虽然没人会考虑使用这种方式来保存数据,但这对于理解序列化流有很大的帮助。

2.2.案例二:任意元素类型的List 集合序列化读写

**
* 任意元素类型的List 集合的对象存储到普通文件,读取直接使用
* @param <T>
*/
public class ObjectList<T extends List> {
// 序列化保存到普通文件
private File file = new File("D:/demoList.txt");

public void writerList(T t) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(t);
objectOutputStream.close();
}

public T readList() throws IOException, ClassNotFoundException {
// 读取普通文件反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
T t = (T) objectInputStream.readObject();
objectInputStream.close();
return t;
}

public boolean isExists(){
return file.exists();
}
public boolean delete(){
return file.delete();
}

// 测试
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectList<List<Person>> objectList = new ObjectList<>();
//数据准备:集合类都实现了序列化接口Serializable
List<Person> list = new ArrayList<>();
list.add(new Person("张三",38,"男"));
list.add(new Person("李四",38,"男"));
list.add(new Person("如花",18,"女"));
// 持久化对象数据
objectList.writerList(list);
// 查询持久化对象数据
List<Person> personList = objectList.readList();
System.out.println("遍历持久化对象数据>");
for (Person person:personList){
System.out.println(person);
if (person.getAge()==38){// 修改年龄38的都改为18
person.setAge(18);
}
}
// 修改后持久化对象数据
objectList.writerList(personList);
System.out.println("遍历修改持久化对象数据>");
List<Person> personList1 = objectList.readList();
for (Person person:personList1){
System.out.println(person);
}
// 删除对象存储的持久化文件
if (objectList.isExists()){
System.out.println("删除对象存储的持久化文件");
objectList.delete();
}

}

}

序列化的目的

  • 序列化流目的:把对象模型数据按序列化规则进行转化,转化后的数据可以保存到磁盘文本或通过网络传输;
  • 反序列化流目的:把磁盘文件或网络传输的序列化数据按反序列化规则进行转化,恢复成对象模型数据,在程序中可直接操作对象模型数据。

前面的案例都是程序和磁盘的IO操作,接下来的是序列化对象通过网络传输的案例。

2.3.案例三:自己实现Java RMI(远程方法调用)

Java RMI(Remote Method Invocation)Java 远程方法调用,是Java编程语言里的一种用于实现远程方法调用的应用程序编程接口。RMI的宗旨就是尽可能简化远程接口对象的使用。

相类似的远程过程调用RPC(Remote Procedure Call),指的是一个进程调用另一个进程(本地或远程主机的进程)的过程。Java 的 RMI 则在 RPC 的基础上向前又迈进了一步,既提供了分布式对象间的通讯。但Java RMI仅限于Java语言间相互调用,无法实现不同语言间的远程方法调用。

在这感受下怎么实现远程方法调用,好玩时刻来了。

!!!高能预警!!!

篇幅原因,请移步到:​ ​自己写了个Java RMI(远程方法调用) 的实现案例​

Java序列化流的奇妙之旅_序列化_04

Java序列化流的奇妙之旅_java_05

 ​Java往期文章​

 ​Java全栈学习路线、学习资源和面试题一条龙​

 ​我心里优秀架构师是怎样的?​

 ​免费下载经典编程书籍​

更多优质文章和资源👇

Java序列化流的奇妙之旅_java_06

原创不易:分享,点赞👇


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK