ProtoBuf序列化

using System.Collections;
using System.IO;
using System;
using ProtoBuf;

/// <summary>
/// 网络协议数据打包和解包类
/// </summary>
public class PackCodec{
    /// <summary>
    /// 序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="msg"></param>
    /// <returns></returns>
    static public byte[] Serialize<T>(T msg)
    {
        byte[] result = null;
        if (msg != null)
        {
            using (var stream = new MemoryStream())
            {
                Serializer.Serialize<T>(stream, msg);
                result = stream.ToArray();
            }
        }
        return result;
    }

    /// <summary>
    /// 反序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="message"></param>
    /// <returns></returns>
    static public T Deserialize<T>(byte[] message)
    {
        T result = default(T);
        if (message != null)
        {
            using (var stream = new MemoryStream(message))
            {
                result = Serializer.Deserialize<T>(stream);
            }
        }
        return result;
    }
}

### 使用 Protobuf 进行序列化 #### C++ 中使用 Protobuf 序列化 在 C++ 中,为了实现高效的序列化和反序列化操作,开发者需先定义 `.proto` 文件中的消息格式。此文件描述了数据结构,之后利用 Protocol Buffers 编译器 (`protoc`) 将其转换成目标语言的源代码[^1]。 ```cpp // 定义 .proto 文件 (example.proto) syntax = "proto3"; message Person { string name = 1; int32 id = 2; } ``` 编译上述 `.proto` 文件会生成相应的 C++ 类 `Person`,该类提供了用于填充对象的方法以及读取/写入二进制流的功能: ```cpp #include "example.pb.h" using namespace std; void serialize(const Person& person, ofstream& outStream){ if (!person.SerializeToOstream(&outStream)) { cerr << "Failed to write message." << endl; } } bool deserialize(ifstream& inStream, Person* person){ return person->ParseFromIstream(&inStream); } ``` 这段代码展示了如何创建一个简单的 `Person` 对象实例,并将其序列化到磁盘上的文件中,同时也说明了从输入流解析回原始对象的过程。 #### Unity(C#) 中使用 Protobuf 序列化 对于 Unity 开发者来说,在项目里集成 Protobuf 主要涉及几个步骤:编写 `.proto` 文件以声明所需的数据模型;接着借助 protoc 工具生成对应的 C# 类型;最后引入必要的库以便能够在应用程序内执行序列化动作[^2]。 ```csharp public void SaveToFile(string filePath, Animal animalData){ using(var file = File.Create(filePath)){ Serializer.Serialize(file, animalData); // 序列化过程 } } public Animal LoadFromFile(string filePath){ using(var file = File.OpenRead(filePath)){ return Serializer.Deserialize<Animal>(file); // 反序列化过程 } } ``` 此处展示了一个名为 `SaveToFile()` 和 `LoadFromFile()` 的函数对,它们分别负责保存和加载基于之前定义好的 `Animal` 结构体的对象至指定路径下的文件中。 #### 利用 SharpZipLib 压缩已序列化的数据 当涉及到较大规模的数据集时,考虑采用压缩技术来减少存储空间占用或加快网络传输速度是有意义的选择之一。SharpZipLib 是一款流行的开源.NET 数据压缩组件,可用于配合 ProtoBuf 实现这一点[^3]。 ```csharp byte[] Compress(List<int> list){ var ms = new MemoryStream(); using(GZIPOutputStream gzipOut = new GZIPOutputStream(ms)){ Serializer.Serialize(gzipOut, list); } return ms.ToArray(); } List<int> Decompress(byte[] compressedBytes){ using(MemoryStream input = new MemoryStream(compressedBytes)) using(GZIPInputStream gzipIn = new GZIPInputStream(input)){ return Serializer.Deserialize<List<int>>(gzipIn); } } ``` 以上片段实现了列表类型的整数集合被序列化后经由 GZIP 算法压缩为字节数组的形式存贮起来,反之亦然——即可以从给定的压缩包恢复原来的数值列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值