简单理解:序列化与反序列化

124 阅读2分钟

序列化(Serialization)和反序列化(Deserialization)是计算机科学中两个核心概念,尤其在网络通信、数据存储和分布式系统中扮演着至关重要的角色。让我详细解释这两个过程及其实际应用。

1、基本概念

1.1 序列化(Serialization)

序列化是将数据结构或对象状态转换为可以存储或传输的格式的过程。这个格式通常是:

  • 字节序列(二进制格式)
  • JSON 或 XML(文本格式)
  • Protocol Buffers 或 MessagePack(紧凑二进制格式)
graph LR
    A[内存中的对象] --> B[序列化]
    B --> C[字节流/文本]

关键特点

  • 平台无关:序列化后的数据可以在不同系统间传输
  • 持久化:可将对象状态保存到文件或数据库中
  • 网络传输:适合在网络上发送数据

1.2 反序列化(Deserialization)

反序列化是将序列化后的数据恢复为原始数据结构或对象的过程

graph LR
    C[字节流/文本] --> D[反序列化]
    D --> A[内存中的对象]

关键特点

  • 重建对象:从序列化数据中恢复原始对象状态
  • 类型安全:确保重建的对象与原始对象类型一致
  • 完整性:保持对象关系和引用结构

2、为什么需要序列化和反序列化?

2.1 网络通信

当客户端和服务器通信时:

  • 客户端将请求对象序列化为字节流
  • 通过网络发送字节流
  • 服务器反序列化字节流为对象
  • 服务器处理请求并序列化响应
  • 客户端反序列化响应

2.2 数据持久化

将内存中的对象保存到文件或数据库

2.3 进程间通信

在不同进程或服务间传递复杂数据结构

3、序列化格式对比

格式类型特点适用场景
JSON文本人类可读,广泛支持Web API,配置文件
XML文本复杂结构,支持Schema企业级系统,SOAP服务
Protocol Buffers二进制高效,类型安全,向前/向后兼容微服务通信,高性能系统
MessagePack二进制比JSON更紧凑,支持扩展类型移动应用,IoT设备
BSON二进制JSON的二进制扩展,支持二进制数据MongoDB数据库存储
Java Serialization二进制平台特定,包含完整类型信息JVM应用内部通信

4、JavaScript中的序列化与反序列化

4.1 json 方法

const obj = {
    name: "John",
    age: 30,
    hobbies: ["reading", "hiking"],
    metadata: {
        createdAt: new Date(),
        isAdmin: true
    }
};

// 序列化
const jsonString = JSON.stringify(obj);
console.log(jsonString);
// 输出: {"name":"John","age":30,"hobbies":["reading","hiking"],"metadata":{"createdAt":"2023-05-15T08:30:00.000Z","isAdmin":true}}

// 反序列化
const parsedObj = JSON.parse(jsonString);
console.log(parsedObj.metadata.createdAt); 
// 输出: "2023-05-15T08:30:00.000Z" (字符串,不是Date对象)

注意事项: 不是深克隆,导致一些数据丢失(循环引用、Map、Set、Date、继承、等)

4.2 SuperJSON(推荐)

import superjson from 'superjson';

const user = {
    name: "Alice",
    createdAt: new Date(),
    permissions: new Set(["read", "write"]),
    metadata: new Map([["id", 123]])
};

// 序列化
const serialized = superjson.stringify(user);

// 反序列化
const deserialized = superjson.parse(serialized);

console.log(deserialized.createdAt instanceof Date); // true
console.log(deserialized.permissions instanceof Set); // true
console.log(deserialized.metadata instanceof Map); // true