当前位置: 首页 > news >正文

序列化与反序列化(一)

注:(此篇重序列化)

一:基础含义

序列化(Serialization)​ 和 反序列化(Deserialization)​ 是计算机中非常基础、也非常常用的概念,用来解决「对象如何在系统之间传输或存储」的问题

  • 序列化:把内存中的对象 → 转换成可存储 / 可传输的格式
  • 反序列化:把存储 / 传输后的数据 → 还原成内存中的对象

二:序列化存在的原因

最大且最根本————转换并储存对象

对象

内存里的对象很脆弱且孤立,而现实世界的数据需要被长久保存或跨系统流动

为什么要转换对象呢?主要有三个原因:

1. 内存断电即失(为了“存得住”)

  • 内存(RAM)​ 就像办公桌,速度快但断电后东西就没了。
  • 如果你不把对象转换成 文件(硬盘)​ 这种格式,程序一旦关闭,内存中的数据就消失了。
  • 转换的目的:把桌上的文件归档到档案柜里,实现持久化

2. 程序不能跨进程(为了“传得动”)

  • 你电脑里的微信(一个程序)和服务器(另一个程序)是互不相连的。内存里的对象无法直接跳过去。
  • 转换的目的:把对象变成一段通用的“字符串”或“字节流”(比如 JSON),通过网络像寄快递一样发过去。

3.不同语言/系统看不懂对方(为了“跨平台”)

  • Java 的对象和 Python 的对象结构完全不同,各自的内存格式也互不兼容。
  • 转换的目的:使用大家都能看懂的通用格式(如 JSON),实现跨语言、跨平台的数据交换。

总结:转换对象,就是为了把“易逝的、私有的”数据,变成“稳定的、通用的”数据,从而能够存下来或者发出去

通过对对象的深刻了解,我们可知

对象与序列化的关系

序列化即将对象的状态信息转换为可以存储或传输的形式的过程(序列化是一种用来处理对象流的机制。所谓对象流也就是将对象的内容进行流化,流(就是I/O)。我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化)

在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象

简单来说,序列化就是把一个对象变成可以传输的字符串,可以以特定的格式在进程之间跨平台、安全的进行通信。

三:序列化的过程示意

内存中的对象 ↓ 序列化 JSON / XML / 二进制 ↓ 存储 or 网络传输 JSON / XML / 二进制 ↓ 反序列化 内存中的对象

示例(JSON 为例)

(1)Java 对象

class User { String name; int age; }

(2)序列化(对象 → JSON)

{ "name": "张三", "age": 18 }

(3)反序列化(JSON → 对象)

User user = parseJson(jsonString);

四:常见序列化方式对比

此处用表格举例(内容来至网络查询)

类型特点常见场景
JSON可读性强、跨语言Web API、前后端通信
XML结构严谨、冗长老系统、企业级接口
二进制体积小、速度快Java RMI、游戏、内部 RPC
Protobuf高效、强约束微服务、高性能通信
YAML可读性好配置文件

五:序列化中常用魔术方法

在序列化与反序列化过程中,不同编程语言会定义一些“魔术方法”(Magic Methods / 特殊方法),由运行时在特定阶段自动调用

这里详细列出了PHP,python,Java​ 中常见的魔术方法

(1):PHP 中的序列化魔术方法

  1. __sleep():在序列化前触发,用于返回需要被序列化的属性数组
  2. __wakeup():在反序列化后触发,用于重新初始化资源、连接等
  3. __serialize():在序列化时触发,用于自定义序列化数据
  4. __unserialize():反序列化时触发,用于自定义反序列化逻辑
  5. __toString():对象被当作字符串时触发,常与调试、日志相关

示例:

class User { public $name; public function __sleep() { return ['name']; // 只序列化 name } public function __wakeup() { echo "对象被恢复了"; } }

注:__wakeup()常被用于构造 PHP 反序列化漏洞(POP Chain)

(2):Python 中的序列化魔术方法

Python的pickle模块(知识点补充在末尾)使用魔术方法来控制对象的序列化行为

(题外话:事实证明表格确实比列表更轻松)

方法触发时机说明
__getstate__()序列化时返回要序列化的状态
__setstate__()反序列化时恢复对象状态
__reduce__()序列化时最重要,可指定构造函数
__reduce_ex__()序列化时__reduce__()的高级版本

示例:

import pickle class User: def __init__(self, name): self.name = name def __getstate__(self): return {'name': self.name} def __setstate__(self, state): self.name = state['name']

注:_reduce__()可被用于 任意代码执行,因此 永远不要用 pickle 反序列化不可信数据

(3)Java 中的序列化方法(不是严格意义上的“魔术方法”,但等价)

Java 使用接口 + 特定方法签名来实现序列化控制。

方法作用
writeObject(ObjectOutputStream out)自定义写入对象
readObject(ObjectInputStream in)自定义读取对象
readResolve()替换反序列化后的对象(单例保护)
writeReplace()替换序列化前的对象
serialVersionUID控制版本兼容性

未完待续

知识补充:pickle

pickle是 Python 标准库中的一个序列化模块,作用是:

把 Python 对象转换成字节流(序列化),以及把字节流还原成 Python 对象(反序列化)

即:Python 专属的“对象打包 / 解包工具”(ps:某种意义上)

(注:我会写一篇新的wp介绍pickle,此处不再啰嗦)

http://www.jsqmd.com/news/972096/

相关文章:

  • 告别调参玄学:用WB可视化工具深度复盘我的第一个Kaggle房价预测项目
  • 洗衣机控制系统 FPGA 设计 Verilog Quartus
  • StackGAN-v2架构深度解析:理解堆叠生成对抗网络的秘密
  • STM32F4的Flash读写避坑指南:从扇区选择到数据安全,我的踩坑记录
  • 第二板块:Android 四大组件标准化学理 | 第六篇:四大组件架构总论与 Manifest 规范
  • [从0开始学Java|第二十七天]IO(异常File)
  • Randall-Sundrum膜世界中的紧凑物体构建与稳定性分析
  • 别再手动调格式了!用Jaspersoft Studio 6.2.0搞定PDF报表排版(附常见报错解决)
  • 电商图片下载工具技术原理:从浏览器内核到智能分类
  • 别再为没有PDB文件发愁了:用JetBrains dotPeek搭建本地符号服务器,轻松调试任意NuGet包源码
  • OriginPro 2021b 保姆级教程:三步搞定多曲线填充面积图,告别数据遮盖烦恼
  • 信号处理入门:5分钟搞懂Butterworth滤波器阶数与截止频率怎么选
  • 考研复习 Day 47 | 密码学--第七章 公钥密码(下)
  • 从Wi-Fi信号到音频均衡器:手把手拆解幅频/相频在真实电子设备中的应用
  • ESP32 ADC测量不准?深入排查Wi-Fi干扰、供电噪声与代码配置(避坑指南)
  • ESP32-S3驱动WS2812灯带:从原理图到代码,手把手搞定RMT配置
  • 别再到处找图了!我整理了全套Apriltag TAG16H5高清大图(附Python脚本一键下载)
  • ёRadio显示配置全攻略:OLED、TFT屏幕驱动与界面定制
  • 软件工程期末自救指南:避开这10个高频易错点,轻松拿下简答题和名词解释
  • TVA与MES/SCADA对接关键协议兼容方案
  • 拼多多商品图片视频批量采集:整店自动分类与高清原图
  • 别再被MicroLIB坑了!N32G45X串口打印printf的两种正确打开方式(Keil MDK实战)
  • AI 制造 AI 的奇点:深度解析“递归自我改进(RSI)”
  • 【花雕学编程】Arduino BLDC 之自主避障式辐射侦察机器人
  • 六年之约第二年年度目标
  • SpringBoot+Vue书店管理系统源码+论文
  • 避坑指南:ADS链路预算仿真时,BudNF控件报错或结果不准?可能是你没用对这个隐藏功能
  • 从FLM到烧录器:保姆级教程教你为自制的CMSIS-DAP离线下载器生成专属下载算法
  • 别再混淆了!一文讲透SAP WM里仓储单位SU、HU和Quant的区别与联系
  • 操作系统知识点