ProtoBuf练习(一)

基础数据类型

protobuf语言的基础字段类型相当于C++语言的基础类型

工程目录结构
$ ls proto/
TFixed.proto  TInt.proto  TScalar.proto  TStr.proto
proto文件
$ cat TScalar.proto
syntax = "proto3";

//导入其他message
import "TInt.proto";
import "TFixed.proto";
import "TStr.proto";

//使用其他message作为字段类型,如果message使用了package则需要使用package.的方式引用
message TScalar {
    scalar.TInt int_val = 1;
    TFixed fixed_val = 2;
    TStr str_val = 3;
};

$ cat TInt.proto
syntax = "proto3";

// 设置包名,在生成的C++源码中将变成namespace
package scalar;

message TInt {
    double ddouble_val = 1;
    float float_val = 2;
    int32 int32_val = 3;
    uint32 uint32_val = 4;
    sint32 sint32_val = 5;
    bool bool_val = 6;
};

$ cat TFixed.proto
syntax = "proto3";

message TFixed {
    fixed32 fixed32_val = 1;
    fixed64 fixed64_val = 2;
    sfixed32 sfixed32_val = 3;
    sfixed64 sfixed64_val = 4;
};

$ cat TStr.proto
syntax = "proto3";

message TStr {
    string string_val = 1;
    bytes bytes_val = 2;
};
读写源文件
$ cat writer.cpp
#include <fstream>
#include <iostream>
#include "TScalar.pb.h"

using namespace std;

int main(int argc, char *argv[])
{
    TScalar msg;
    scalar::TInt* iMsg = new scalar::TInt();
    TFixed* fMsg = new TFixed();
    TStr* sMsg = new TStr();
    // 使用protobuf自己的内存管理
    msg.set_allocated_int_val(iMsg);
    msg.set_allocated_fixed_val(fMsg);
    msg.set_allocated_str_val(sMsg);

    iMsg->set_ddouble_val(11.01);
    iMsg->set_float_val(11.01);
    iMsg->set_int32_val(-1);
    iMsg->set_uint32_val(1);
    iMsg->set_sint32_val(-1);
    iMsg->set_bool_val(true);

    fMsg->set_fixed32_val(1);
    fMsg->set_fixed64_val(1);
    fMsg->set_sfixed32_val(-1);
    fMsg->set_sfixed64_val(-1);

    sMsg->set_string_val("中");
    sMsg->set_bytes_val("文");

    fstream output("./log", ios::out | ios::trunc | ios::binary);
    cout << "Serialize start." << endl;
    if (!msg.SerializeToOstream(&output))
        {
                cout << "Serialize failed." << endl;
                return -1;
        }
    output.close();
    cout << "Serialize end." << endl;
    return 0;
}

$ cat reader.cpp
#include <fstream>
#include <iostream>
#include "TScalar.pb.h"

using namespace std;

int main(int argc, char *argv[])
{
    fstream input("./log", ios::in | ios::binary);
    cout << "Deserialize start." << endl;

    TScalar msg;
    //如果writer依次写入TInt、TFixed、TStr,然后在reader依次读取TInt、TFixed、TStr,这时只有第一个message能正常解析,后两条message解析失败,因为ParseFromIstream会一次性把input流内容读完,导致后面的message解析时读取的输入流已经为空,所以表面上看起来就好像protocol buffer只能序列化和反序列化一条message
    if (!msg.ParseFromIstream(&input))
    {
        cout << "Deserialize failed." << endl;
        return -1;
    }
    msg.int_val().PrintDebugString();
    msg.fixed_val().PrintDebugString();
    msg.str_val().PrintDebugString();

    cout << "Deserialize end." << endl;
    input.close();
    return 0;
}

转载于:https://www.cnblogs.com/silvermagic/p/9087607.html

您好!如果您想练习使用 Go 与 Protocol Buffers(简称 Protobuf)进行开发,我可以给您一些建议和示例。 首先,确保您已经安装了 Go 编程语言和 Protocol Buffers 工具。然后,您可以按照以下步骤进行练习: 1. 定义消息格式:创建一个 `.proto` 文件来定义您的消息格式。例如,假设您要创建一个简单的用户信息消息,可以创建一个名为 `user.proto` 的文件,并编写以下内容: ```protobuf syntax = "proto3"; package user; message User { string name = 1; int32 age = 2; } ``` 2. 生成代码:使用 `protoc` 工具将 `.proto` 文件编译为 Go 代码。在终端中运行以下命令: ```shell protoc --go_out=. user.proto ``` 这将在当前目录下生成一个 `user.pb.go` 的文件,其中包含了生成的 Go 结构体和相关方法。 3. 使用生成的代码:在您的 Go 代码中导入生成的文件并使用其中定义的结构体和方法。例如,您可以编写以下代码来创建一个新用户并将其序列化为字节流: ```go package main import ( "fmt" "log" "github.com/your-module-path/user" "google.golang.org/protobuf/proto" ) func main() { newUser := &user.User{ Name: "Alice", Age: 30, } data, err := proto.Marshal(newUser) if err != nil { log.Fatal(err) } fmt.Println(data) } ``` 以上代码导入了 `user.pb.go` 文件,并创建了一个名为 `newUser` 的用户对象。然后,使用 `proto.Marshal` 方法将其序列化为字节流,并打印输出。 这只是 Protobuf 的基本用法示例,您还可以使用更多功能,如嵌套消息、枚举类型、自定义选项等。请查阅 Protobuf 官方文档以获取更多详细信息和示例:https://developers.google.com/protocol-buffers/docs/gotutorial 祝您练习愉快!如果您还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值