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

各种语言的序列化与反序列化(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 };

        // 序列化为 XML
        XmlSerializer 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.jsmsgpack.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;
    }

    @Override
    public 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:用于确保类的版本兼容性。每次修改类的结构时,必须更新该值,避免反序列化时出现不匹配问题。
  • ObjectOutputStreamObjectInputStream:用于对象序列化和反序列化的输入输出流。

1.2 JSON 序列化与反序列化

Java 通过第三方库如 GsonJackson 可以实现对象的 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;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeInt(age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        age = in.readInt();
    }

    @Override
    public 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.stringifyJSON.parse 实现 JSON 序列化与反序列化。
  • Java 主要通过 实现 java.io.Serializable 接口 和 Gson 或 Jackson 等第三方库 实现 JSON 序列化与反序列化。

http://www.kler.cn/news/356355.html

相关文章:

  • 【C++】string类(接口使用详解 下)
  • c++中,经常需要用来获取用户输入的写法,或者暂停【防止终端退出】
  • MySQL中8.0为啥引入索引跳跃扫描(Index Skip Scan)
  • 基于DE1-SOC的My_first_fpga
  • 14.归一化——关键的数据预处理方法
  • 汽车与航空领域的功能安全对比:ISO 26262-6 与 DO-178C 的差异浅析
  • 【分布式微服务云原生】《Redis 大 Key 和热点 Key:问题与解决方案全攻略》
  • Python画笔案例-083 绘制 3D世界坐标轴
  • Gin框架操作指南04:GET绑定
  • Python编程探索:从基础语法到循环结构实践(下)
  • python高级函数详解
  • [含文档+PPT+源码等]精品基于Nodejs实现的微信小程序校园心理健康平台设计与实现
  • Unity性能优化
  • 拓扑学与集合论的关系
  • 除了 Python,还有哪些语言适合做爬虫?
  • 从空口分析经典蓝牙A2DP和AVRCP协议
  • 2012年国赛高教杯数学建模A题葡萄酒的评价解题全过程文档及程序
  • 周末总结(2024/10/19)
  • GDAL+C#实现矢量多边形转栅格
  • ●day 35 动态规划part01