序列化是指将程序中的对象转换为字节序列的过程,使得对象的状态可以在网络上传输或存储到文件中。反序列化则是将字节序列恢复为程序中的对象的过程。这两个过程是数据持久化和远程通信中的关键步骤。
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 序列化与反序列化。