Protobuf:一种轻量级、高效的数据交换格式,附Java与Python数据交换示例

简介: Protobuf:一种轻量级、高效的数据交换格式,附Java与Python数据交换示例

目录

下载安装Protobuf

定义数据格式

Java代码序列化

Python反序列化

Protobuf(Protocol Buffers)是由 Google 开发的一种轻量级、高效的数据交换格式


官方文档:https://protobuf.dev/overview/

GitHub:https://github.com/protocolbuffers/protobuf

https://github.com/protocolbuffers/protobuf/releases/latest

VSCode语法高亮插件:vscode-proto

本文仅做一个简单的代码演示,并不涉及原理说明


本文演示如何将Java数据通过文件的方式传递给Python


9682c201b800da6799bd08792964858f_eb7966630daf4613bc3e19d9fb7b8602.png

项目结构


protobuf-demo/

 protobuf-data        # 定义通用的数据结构

 protobuf-java        # Java项目序列化protobuf

 protobuf-python      # Python项目反序列化protobuf


下载安装Protobuf

# 检查系统版本

$ sw_vers

ProductName:    Mac OS X

ProductVersion: 10.14.4

BuildVersion:   18E2035


# 下载解压 protoc-23.0-osx-x86_64.zip


$ ./bin/protoc --version

libprotoc 23.0


定义数据格式

protobuf-data/addressbook.proto


// 文件:addressbook.proto


// 指定 Protobuf 版本为版本3

syntax = "proto3";

// 指定 protobuf 包名,防止有相同类名的 message 定义

package com.example.protobuf;

// 是否生成多个文件

option java_multiple_files = true;

// 生成的文件存放在哪个包下

option java_package = "com.example.protobuf";

// 生成的类名,如果没有指定,会根据文件名自动转驼峰来命名

option java_outer_classname = "AddressBookProtos";


message Person {

 // =1,=2 作为序列化后的二进制编码中的字段的唯一标签,也因此,1-15 比 16 会少一个字节,所以尽量使用 1-15 来指定常用字段。

 optional int32 id = 1;

 optional string name = 2;

 optional string email = 3;


 enum PhoneType {

   MOBILE = 0;

   HOME = 1;

   WORK = 2;

 }


 message PhoneNumber {

   optional string number = 1;

   optional PhoneType type = 2;

 }


 repeated PhoneNumber phones = 4;

}


message AddressBook {

 repeated Person people = 1;

}



使用 Protobuf 提供的编译器,可以将 .proto 文件编译成各种语言的代码文件(如 Java、C++、Python 等)。


572bf2f9c894b44ad13db87b195fea06_1760c47412b84ac2988e33595c3aaa3d.png

Java代码序列化

依赖


<dependency>

   <groupId>com.google.protobuf</groupId>

   <artifactId>protobuf-java</artifactId>

   <version>3.22.3</version>

</dependency>


生成java代码


./bin/protoc --java_out=../protobuf-java/src/main/java ./addressbook.proto

1

项目结构


$ tree

.

├── pom.xml

├── protobuf-java.iml

└── src

   ├── main

   │   └── java

   │       └── com

   │           └── example

   │               └── protos

   │                   ├── AddressBook.java

   │                   ├── AddressBookOrBuilder.java

   │                   ├── AddressBookProtos.java

   │                   ├── Person.java

   │                   └── PersonOrBuilder.java

   └── test

       └── java

           └── com

               └── example


构建测试


package com.example;


import com.example.protos.AddressBook;

import com.example.protos.Person;

import org.junit.Test;


public class ProtobufTest {

   @Test

   public void testBuildProtobuf(){

       //  构建

       AddressBook addressBook = AddressBook

               .newBuilder()

               .addPeople(Person.newBuilder()

                       .setId(2)

                       .setName("小明")

                       .setEmail("yyds@126.com")

                       .addPhones(Person.PhoneNumber.newBuilder()

                               .setNumber("18388888888")

                               .setType(Person.PhoneType.HOME)

                       )

               )

               .build();

       System.out.println(addressBook);

   }

}



输出


people {

 id: 2

 name: "\345\260\217\346\230\216"

 email: "yyds@126.com"

 phones {

   number: "18388888888"

   type: HOME

 }

}



序列化


// 序列化成字节数组

byte[] byteArray = addressBook.toByteArray();

// 反序列化 - 字节数组转对象

AddressBook addressBook2 = AddressBook.parseFrom(byteArray);

System.out.println("字节数组反序列化:");

System.out.println(addressBook2);


// 序列化到文件

addressBook.writeTo(new FileOutputStream("AddressBook.txt"));

// 读取文件反序列化

AddressBook addressBook3 = AddressBook.parseFrom(new FileInputStream("AddressBook.txt"));

System.out.println("文件读取反序列化:");

System.out.println(addressBook3);


AddressBook.txt



)小明yyds@126.com"

18388888888


Python反序列化

安装依赖


pip install protobuf


生成Python代码


./bin/protoc --python_out=../protobuf-python ./addressbook.proto


目录


$ tree -I venv

.

├── AddressBook.txt            # 由上一步java代码输出的数据文件

├── addressbook_pb2.py         # 自动生成的文件

└── demo.py


反序列化示例 demo.py


# -*- coding: utf-8 -*-

"""

@File    : demo.py

@Date    : 2023-05-12

"""

import addressbook_pb2


if __name__ == '__main__':

   # 反序列化

   with open('AddressBook.txt', 'rb') as f:

       addressBook = addressbook_pb2.AddressBook()

       addressBook.ParseFromString(f.read())



       for person in addressBook.people:

           print(person.name)

           # 小明


直接打印addressBook对象


people {

 id: 2

 name: "\345\260\217\346\230\216"

 email: "yyds@126.com"

 phones {

   number: "18388888888"

   type: HOME

 }

}



Python的体验不是很好,代码提示的能力基本为零,需要使用dir(obj)查看对象属性才知道


完整代码:https://github.com/mouday/protobuf-demo


参考

Protobuf: 高效数据传输的秘密武器

Python使用protobuf序列化和反序列化

————————————————

版权声明:本文为CSDN博主「彭世瑜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/mouday/article/details/130639021

相关文章
|
2天前
|
网络安全 流计算 Python
实时计算 Flink版操作报错合集之Flink sql-client 针对kafka的protobuf格式数据建表,报错:java.lang.ClassNotFoundException 如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
15 1
|
4天前
|
消息中间件 关系型数据库 网络安全
实时计算 Flink版操作报错合集之Flink sql-client 针对kafka的protobuf格式数据建表,报错:java.lang.ClassNotFoundException 如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
14 1
|
4天前
|
SQL Java 数据处理
实时计算 Flink版产品使用合集之怎么热加载Java和Python的UDF
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
11 1
|
6天前
|
SQL 测试技术 网络安全
Python之SQLMap:自动SQL注入和渗透测试工具示例详解
Python之SQLMap:自动SQL注入和渗透测试工具示例详解
29 0
|
6天前
|
前端开发 文件存储 Python
python之xhtml2pdf: HTML转PDF工具示例详解
python之xhtml2pdf: HTML转PDF工具示例详解
13 0
|
6天前
|
语音技术 开发者 Python
python之pyAudioAnalysis:音频特征提取分析文档示例详解
python之pyAudioAnalysis:音频特征提取分析文档示例详解
20 0
|
6天前
|
数据采集 数据挖掘 Python
Python之html2text: 将HTML转换为Markdown 文档示例详解
Python之html2text: 将HTML转换为Markdown 文档示例详解
10 0
|
6天前
|
存储 JSON 编解码
python之simplejson:JSON 编/解码器示例详解
python之simplejson:JSON 编/解码器示例详解
10 0
|
6天前
|
JSON 数据格式 索引
python之JMESPath:JSON 查询语法库示例详解
python之JMESPath:JSON 查询语法库示例详解
16 0
|
6天前
|
存储 数据处理 Python
python 之map、zip和filter迭代器示例详解
python 之map、zip和filter迭代器示例详解
10 0