序列化和反序列化
Java 序列化是一种将对象转换为字节流的过程,以便可以将对象保存到磁盘上,将其传输到网络上,或者将其存储在内存中,以后再进行反序列化,将字节流重新转换为对象。
序列化在 Java 中是通过 java.io.Serializable 接口来实现的,该接口没有任何方法,只是一个标记接口,用于标识类可以被序列化。
当你序列化对象时,你把它包装成一个特殊文件,可以保存、传输或存储。反序列化则是打开这个文件,读取序列化的数据,然后将其还原为对象,以便在程序中使用。
传输对象
实现 Serializable
接口: 要使一个类可序列化,需要让该类实现 java.io.Serializable
接口,这告诉 Java 编译器这个类可以被序列化.
1 | public class User implements java.io.Serializable { //该接口没有任何方法,只是一个标记接口,用于标识类可以被序列化。 |
java.io.ObjectOutputStream
代表对象输出流,它的**writeObject(Object obj)**方法可对参数指定的obi对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream
代表对象输入流,它的**readObject()**方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
通过Socket传输对象
客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class userClient {
public static void main(String[l args){
//创建客户端socket,指定服务器的p和端口
try {
Socket socket = new Socket("127.0.0.1",9999);
//获取该socket的输出流,用来向服务器发送信息
OutputStream os=socket.getOutputStream();
ObiectOutputStream oos =new ObjectOutputStream(os);
//序列化user对象,以字节序列输出
oos.writeObject(new User(1, "root","123456"));
socket.shutdownOutput();
//获取输入流,取得服务器的信息
InputStream is= socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while ((info = br.readLine())!= null){
System.out.println("服务器的信息是:"+ info)
}
}
}服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class ServerHandleThread implements Runnable{ //表示该类的实例可以被一个线程执行
Socket socket=null;
public ServerHandleThread(Socket socket){
super();
this.socket= socket;
}
public void run() {
OutputStream os = null;
PrintWriter pw = null;
try {
InputStream is = socket.getInputStream();
ObjectInputStream ois=new ObjectInputStream(is);
//从客户端读取字节序列,反序列化为对象
System.out.println("客户端发送的对象:"+(User) ois.readObject());
socket.shutdownInput();// 关闭套接字的输入流,连接并未关闭
os=socket.getOutputStream();
pw=new PrintWriter(os);
pw.println("欢迎登录!");
pw.flush();
socket.shutdownOutput();
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public class simpleServer {
public static void main(String[] args){
try {
ServerSocket serverSocket =new ServerSocket(9999);
intcount=0://记录客户端的数量
System.out.println("服务器启动,等待客户端的连接。。。");
Socket socket = null;
while(true){
socket=serverSocket.accept();
++count;
//调用线程函数
Thread serverHandleThread=new Thread(new ServerHandleThread(socket));
serverHandleThread.setPriority(4);
serverHandleThread.start();
System.out.println("上线的客户端有"+ count+"个!");
InetAddress inetAddress=socket.getInetAddress();
System.out.println("当前客户端的!P地址是:"+inetAddress.getHostAddress());
}
}catch(lOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
存储对象
序列化对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}- 当序列化一个对象到文件时, 按照 Java 的标准约定是给文件一个 .ser 扩展名
反序列化对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
- 本文作者: NICK
- 本文链接: https://nicccce.github.io/TechNotes/Serialization-and-Deserialization/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!