各种语言的序列化与反序列化(C/C++ c# Python Javascript Java)
序列化是指将程序中的对象转换为字节序列的过程,使得对象的状态可以在网络上传输或存储到文件中。反序列化则是将字节序列恢复为程序中的对象的过程。这两个过程是数据持久化和远程通信中的关键步骤。
1. C++ 序列化与反序列化
在 C++ 中,标准库没有提供内置的序列化与反序列化功能,但可以通过手动编码或使用第三方库(如 Boost.Serialization)实现。
1.1 手动序列化与反序列化
C++ 可以通过文件流(fstream
)或字符串流(stringstream
)手动实现对象序列化与反序列化:
示例:使用 fstream
序列化与反序列化对象
cpp复制代码#include <iostream>
#include <fstream>
#include <string>class Person {
public:std::string name;int age;// 序列化函数void serialize(std::ofstream &out) const {size_t nameLength = name.size();out.write(reinterpret_cast<const char*>(&nameLength), sizeof(nameLength)); // 写入名字长度out.write(name.c_str(), nameLength); // 写入名字内容out.write(reinterpret_cast<const char*>(&age), sizeof(age)); // 写入年龄}// 反序列化函数void deserialize(std::ifstream &in) {size_t nameLength;in.read(reinterpret_cast<char*>(&nameLength), sizeof(nameLength)); // 读取名字长度name.resize(nameLength);in.read(&name[0], nameLength); // 读取名字内容in.read(reinterpret_cast<char*>(&age), sizeof(age)); // 读取年龄}
};int main() {Person p1{"Alice", 30};// 序列化对象到文件std::ofstream outFile("person.dat", std::ios::binary);p1.serialize(outFile);outFile.close();// 反序列化对象从文件Person p2;std::ifstream inFile("person.dat", std::ios::binary);p2.deserialize(inFile);inFile.close();std::cout << "Name: " << p2.name << ", Age: " << p2.age << std::endl;return 0;
}
1.2 使用 Boost.Serialization 库
Boost 提供了一个强大的序列化库,支持文本、二进制和 XML 等多种格式的序列化。
示例:使用 Boost 序列化
cpp复制代码#include <iostream>
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>class Person {
public:std::string name;int age;// 必须声明序列化接口template<class Archive>void serialize(Archive &ar, const unsigned int version) {ar & name;ar & age;}
};int main() {Person p1{"Alice", 30};// 序列化对象std::ofstream outFile("person.txt");boost::archive::text_oarchive oa(outFile);oa << p1;// 反序列化对象Person p2;std::ifstream inFile("person.txt");boost::archive::text_iarchive ia(inFile);ia >> p2;std::cout << "Name: " << p2.name << ", Age: " << p2.age << std::endl;return 0;
}
2. C# 序列化与反序列化
C# 提供了多种内置方法进行序列化与反序列化,如 XML 序列化、二进制序列化、JSON 序列化等。
2.1 JSON 序列化与反序列化(System.Text.Json
)
C# 中常用 System.Text.Json
库进行 JSON 格式的序列化与反序列化。
示例:JSON 序列化与反序列化
csharp复制代码using System;
using System.Text.Json;public class Person {public string Name { get; set; }public int Age { get; set; }
}class Program {static void Main() {Person p1 = new Person { Name = "Alice", Age = 30 };// 序列化为 JSON 字符串string jsonString = JsonSerializer.Serialize(p1);Console.WriteLine("Serialized JSON: " + jsonString);// 反序列化回对象Person p2 = JsonSerializer.Deserialize<Person>(jsonString);Console.WriteLine($"Name: {p2.Name}, Age: {p2.Age}");}
}
2.2 XML 序列化与反序列化(System.Xml.Serialization
)
C# 还可以使用 System.Xml.Serialization
序列化对象为 XML 格式。
示例:XML 序列化与反序列化
csharp复制代码using System;
using System.IO;
using System.Xml.Serialization;public class Person {public string Name { get; set; }public int Age { get; set; }
}class Program {static void Main() {Person p1 = new Person { Name = "Alice", Age = 30 };// 序列化为 XMLXmlSerializer serializer = new XmlSerializer(typeof(Person));using (TextWriter writer = new StreamWriter("person.xml")) {serializer.Serialize(writer, p1);}// 反序列化回对象Person p2;using (TextReader reader = new StreamReader("person.xml")) {p2 = (Person)serializer.Deserialize(reader);}Console.WriteLine($"Name: {p2.Name}, Age: {p2.Age}");}
}
2.3 二进制序列化与反序列化(System.Runtime.Serialization.Formatters.Binary
)
C# 还支持二进制格式的序列化与反序列化。
示例:二进制序列化与反序列化
csharp复制代码using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;[Serializable]
public class Person {public string Name { get; set; }public int Age { get; set; }
}class Program {static void Main() {Person p1 = new Person { Name = "Alice", Age = 30 };// 序列化为二进制BinaryFormatter formatter = new BinaryFormatter();using (FileStream fs = new FileStream("person.dat", FileMode.Create)) {formatter.Serialize(fs, p1);}// 反序列化回对象Person p2;using (FileStream fs = new FileStream("person.dat", FileMode.Open)) {p2 = (Person)formatter.Deserialize(fs);}Console.WriteLine($"Name: {p2.Name}, Age: {p2.Age}");}
}
3. Python 序列化与反序列化
Python 中最常见的序列化方式是使用 json
模块和 pickle
模块。json
用于将数据序列化为 JSON 格式,pickle
用于将 Python 对象序列化为二进制格式。
3.1 JSON 序列化与反序列化(json
模块)
示例:JSON 序列化与反序列化
python复制代码import json# 定义一个 Python 对象
person = {"name": "Alice", "age": 30}# 序列化为 JSON 字符串
json_string = json.dumps(person)
print("Serialized JSON:", json_string)# 反序列化回 Python 对象
person_deserialized = json.loads(json_string)
print("Deserialized Object:", person_deserialized)
3.2 二进制序列化与反序列化(pickle
模块)
示例:使用 pickle
进行二进制序列化与反序列化
python复制代码import pickle# 定义一个 Python 对象
person = {"name": "Alice", "age": 30}# 序列化为二进制数据
with open("person.pkl", "wb") as f:pickle.dump(person, f)# 反序列化回 Python 对象
with open("person.pkl", "rb") as f:person_deserialized = pickle.load(f)print("Deserialized Object:", person_deserialized)
4. JavaScript 序列化与反序列化
JavaScript 中主要使用 JSON 序列化与反序列化,适用于客户端与服务器之间的数据传输。
4.1 JSON 序列化与反序列化(JSON
对象)
JavaScript 原生支持 JSON 的序列化与反序列化。
示例:JSON 序列化与反序列化
javascript复制代码// 定义一个 JavaScript 对象
const person = { name: "Alice", age: 30 };// 序列化为 JSON 字符串
const jsonString = JSON.stringify(person);
console.log("Serialized JSON:", jsonString);// 反序列化回对象
const personDeserialized = JSON.parse(jsonString);
console.log("Deserialized Object:", personDeserialized);
4.2 手动序列化与反序列化
对于复杂的对象,可能需要手动实现序列化与反序列化。JavaScript 不提供对二进制的直接支持,但可以借助其他库(如 protobuf.js
或 msgpack.js
)来实现高级序列化方案。
5. Java 序列化与反序列化
1.1 Java 原生序列化与反序列化
Java 内置支持对象的序列化与反序列化功能,主要通过实现 java.io.Serializable
接口来实现对象的序列化。
实现序列化与反序列化
- 序列化:将 Java 对象转换为字节流,以便将对象保存到文件或通过网络传输。
- 反序列化:将字节流转换回 Java 对象。
示例:Java 原生序列化与反序列化
java复制代码import java.io.*;// 定义一个可序列化的类
class Person implements Serializable {private static final long serialVersionUID = 1L;String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}public class Main {public static void main(String[] args) {Person person = new Person("Alice", 30);// 序列化对象try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {oos.writeObject(person);System.out.println("Object has been serialized");} catch (IOException e) {e.printStackTrace();}// 反序列化对象try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {Person deserializedPerson = (Person) ois.readObject();System.out.println("Deserialized Object: " + deserializedPerson);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}
Serializable
接口:为了让类支持序列化,必须实现Serializable
接口。serialVersionUID
:用于确保类的版本兼容性。每次修改类的结构时,必须更新该值,避免反序列化时出现不匹配问题。ObjectOutputStream
和ObjectInputStream
:用于对象序列化和反序列化的输入输出流。
1.2 JSON 序列化与反序列化
Java 通过第三方库如 Gson 或 Jackson 可以实现对象的 JSON 序列化和反序列化。
示例:使用 Gson 进行 JSON 序列化与反序列化
java复制代码import com.google.gson.Gson;class Person {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}
}public class Main {public static void main(String[] args) {Person person = new Person("Alice", 30);Gson gson = new Gson();// 序列化为 JSON 字符串String jsonString = gson.toJson(person);System.out.println("Serialized JSON: " + jsonString);// 反序列化为对象Person deserializedPerson = gson.fromJson(jsonString, Person.class);System.out.println("Deserialized Object: " + deserializedPerson.name + ", Age: " + deserializedPerson.age);}
}
1.3 Java 使用 Externalizable
接口
与 Serializable
相比,Externalizable
接口提供了更多的控制力,允许开发者定义序列化过程。
示例:使用 Externalizable
接口进行序列化
java复制代码import java.io.*;class Person implements Externalizable {String name;int age;// 必须提供无参数构造函数public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(name);out.writeInt(age);}@Overridepublic void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {name = (String) in.readObject();age = in.readInt();}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}public class Main {public static void main(String[] args) {Person person = new Person("Alice", 30);// 序列化对象try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ext"))) {oos.writeObject(person);System.out.println("Object has been serialized");} catch (IOException e) {e.printStackTrace();}// 反序列化对象try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ext"))) {Person deserializedPerson = (Person) ois.readObject();System.out.println("Deserialized Object: " + deserializedPerson);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}
总结
- C++ 中手动实现序列化常用文件流,Boost 提供了更高级的序列化库。
- C# 提供了丰富的序列化方法,包括 JSON、XML 和二进制序列化。
- Python 中常用
json
模块和pickle
模块进行序列化与反序列化。 - JavaScript 主要通过
JSON.stringify
和JSON.parse
实现 JSON 序列化与反序列化。 - Java 主要通过 实现 java.io.Serializable 接口 和 Gson 或 Jackson 等第三方库 实现 JSON 序列化与反序列化。
相关文章:
各种语言的序列化与反序列化(C/C++ c# Python Javascript Java)
序列化是指将程序中的对象转换为字节序列的过程,使得对象的状态可以在网络上传输或存储到文件中。反序列化则是将字节序列恢复为程序中的对象的过程。这两个过程是数据持久化和远程通信中的关键步骤。 1. C 序列化与反序列化 在 C 中,标准库没有提供内…...
RHCE笔记
第二章:时间服务器 东八区:UTC8CST(北京时间) 应用层的时间协议:NTP(网络时间协议):udp/端口:123 Chrony软件:由chronyd(客户端)和chronyc(服务…...
Android 设置控件为圆形
Android的圆形控件 对于所有的View有效 在开发的过程中,肯定需要实现一个圆形的控件,而且不是绘制一个圆形,那么怎么弄呢,在Android5.0后,有一个类ViewOutlineProvider,可以实现这个功能,应该是…...

qt/c++中成员函数返回成员变量并且可以赋值
#创作灵感 最近在做仪表项目,由于客户提供的仪表故障指示灯只有10个固定位置,而故障指示灯却有80多个。为了解决这个问题,进过我的设计,项目中需要返回类的成员变量。并且还可以赋值给它。于是就产生了下面的代码。 class Foo { …...
【网络安全】IDOR与JWT令牌破解相结合,实现编辑、查看和删除数万帐户
未经许可,不得转载。 文章目录 前言漏洞1漏洞2修复建议在今年4月17日,笔者发过一篇关于 JWT 的文章,未学习过或稍有遗忘的朋友可以点击跳转:【网络安全 | 密码学】JWT基础知识及攻击方式详析 现分享一篇与 JWT 有关的漏洞挖掘案例。 前言 我在某公共漏洞奖励计划的应用程…...

docker安装与镜像打包
文章目录 前言一、docker安装1.1、下载docker安装包1.2、解压1.3、移动1.4、docker注册成系统服务1.5、添加文件权限1.6、设置开机启动1.7、启动docker1.8、测试是否启动 二、镜像加载2.1、镜像准备2.2、加载镜像2.3、查看已加载镜像2.4、进入镜像 三、打包镜像3.1、创建 Docke…...

“新物种”即将上线,极氪MIX是近几年最“好玩”的新车?
像极氪MIX这样有创意的新能源车 除了概念车外,市面上真的很少能看到类似的量产车 别致可爱的造型、新颖的对开门设计、百变的空间布局 同时兼顾了MPV大空间以及SUV的操控乐趣和通过性 妥妥的“新物种” A级车车长D级车轴距,配合隐藏式双B柱电动对开…...
【Flutter】路由与导航:复杂导航与深度链接
在开发大型 Flutter 应用时,复杂的导航管理是不可避免的。除了基本的页面跳转与返回操作外,很多应用会用到 嵌套路由、页面分组、TabBar 和 Drawer 的结合使用等复杂导航场景,甚至支持 深度链接 和 动态路由。本文将深入探讨这些高级导航技巧…...
07 实战:视频捕获
代码如下: import tkinter as tk # 导入tkinter库,用于创建图形用户界面 from tkinter import ttk, filedialog, messagebox # 导入tkinter的额外部件、文件对话框和消息框 import cv2 # 导入OpenCV库,用于图像处理 import numpy as np # 导入NumPy库,用于数值计算 from P…...

前端页面使用google地图api实现导航功能,开发国外网站免费简单好用
开发国外软件的时候,想使用goole map实现导航等功能,可以使用google的api来做,官方文档地址:https://developers.google.com/maps/documentation/urls/get-started?hlzh-cn ,比如: 支持的请求的操作&…...

UE4 材质学习笔记12(水体反射和折射)
一.水体反射和折射 首先就是要断开所有连接到根节点的线,因为水有很多不同的节点成分,当所有其他节点都在用时 要分辨出其中一个是何效果是很难的。 虚幻有五种不同的方法可以创建反射,虚幻中的大多数场景使用多种这些方法 它们会同时运作。…...

Go:error处理机制和函数
文章目录 error处理机制函数函数作为参数匿名函数匿名函数和闭包闭包运用闭包与工厂模式 error处理机制 本篇总结的是Go中对于错误的处理机制 Go 语言的函数经常使用两个返回值来表示执行是否成功:返回某个值以及 true 表示成功;返回零值(或…...

智能指针(3)
目录 可能问题五: 问题分析: 答案格式: shared_ptr的模拟实现 部分1:引用计数的设计(分考点1) 代码实现: 部分2:作为类所必须的部分(分考点2) 代码实现: 部分3:拷贝构造函数…...

spring源码拓展点3之addBeanPostProcesser
概述 在refresh方法中的prepareBeanFactory方法中,有一个拓展点:addBeanPostProcessor。即通过注入Aware对象从而将容器中的某些值设置到某个bean中。 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));aware接口调用 …...

【计网】理解TCP全连接队列与tcpdump抓包
希望是火,失望是烟, 生活就是一边点火,一边冒烟。 理解TCP全连接队列与tcpdump抓包 1 TCP 全连接队列1.1 重谈listen函数1.2 初步理解全连接队列1.3 深入理解全连接队列 2 tcpdump抓包 1 TCP 全连接队列 1.1 重谈listen函数 这里我们使用…...

react18中实现简易增删改查useReducer搭配useContext的高级用法
useReducer和useContext前面有单独介绍过,上手不难,现在我们把这两个api结合起来使用,该怎么用?还是结合之前的简易增删改查的demo,熟悉vue的应该可以看出,useReducer类似于vuex,useContext类似…...

排序算法 —— 冒泡排序
目录 1.冒泡排序的思想 2.冒泡排序的实现 3.冒泡排序的总结 1.冒泡排序的思想 冒泡排序的思想就是在待排序序列中依次比较相邻两个元素,将大的or小的元素往后挪,每一趟都能保证将至少一个元素挪动到正确的位置,然后在待排序序列中重复该过…...

QT--文本框 QLineEdit、qtextedit
在Qt中,文本框(QLineEdit 或 QTextEdit)和标签(QLabel)是两种不同的部件(widget),它们的主要区别在于用途和功能: QLabel(标签) 用途࿱…...

Qt编写的modbus模拟器/支持网络和串口以及websocket/支持网络rtu
一、使用说明 1.1 设备模拟-Com 第一步,填写要模拟的设备地址,0表示自动处理,也就是收到什么地址就应答什么地址。第二步,填写对应的串口号和波特率。第三步,单击打开串口,成功后会变成关闭串口字样。单击…...
Standard_Matrix
文章目录 假设我们有一个样本矩阵X,每一列表示一个样本,现在我们要把样本转换成均值为0,方差为1的样本矩阵 X s t a n d a r d X − μ s \begin{equation} X_{standard}\frac{X-\mu}{s} \end{equation} XstandardsX−μpython 测试…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...