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

相关文章
|
16天前
|
jenkins Shell 测试技术
|
16天前
|
机器学习/深度学习 JSON Java
Java调用Python的5种实用方案:从简单到进阶的全场景解析
在机器学习与大数据融合背景下,Java与Python协同开发成为企业常见需求。本文通过真实案例解析5种主流调用方案,涵盖脚本调用到微服务架构,助力开发者根据业务场景选择最优方案,提升开发效率与系统性能。
156 0
|
16天前
|
安全 jenkins Java
Java、Python、C++支持jenkins和SonarQube(一)
Jenkins 是一个开源的 持续集成(CI)和持续交付(CD) 工具,用于自动化构建、测试和部署软件项目。它基于 Java 开发,支持跨平台运行,并拥有丰富的插件生态系统,可以灵活地扩展功能
73 5
|
16天前
|
jenkins Java Shell
Java、Python、C++支持jenkins和SonarQube(全集)
Jenkins 是一个开源的持续集成(CI)和持续交付(CD)工具,用于自动化构建、测试和部署软件项目。它基于 Java 开发,支持跨平台运行,并拥有丰富的插件生态系统,可以灵活地扩展功能
115 1
|
16天前
|
jenkins Java 持续交付
|
8天前
|
存储 数据库 开发者
Python SQLite模块:轻量级数据库的实战指南
本文深入讲解Python内置sqlite3模块的实战应用,涵盖数据库连接、CRUD操作、事务管理、性能优化及高级特性,结合完整案例,助你快速掌握SQLite在小型项目中的高效使用,是Python开发者必备的轻量级数据库指南。
88 0
|
16天前
|
jenkins Java 测试技术
|
JSON Android开发 iOS开发
Python | 获取iOS设备信息的轻量级框架
今天接着上一篇Python | 获取Android设备信息的轻量级框架,来讲讲如何通过Python实现一个轻量级的库来获取电脑上连接的iOS设备信
510 0
|
16天前
|
数据采集 机器学习/深度学习 人工智能
Python:现代编程的首选语言
Python:现代编程的首选语言
187 102
|
16天前
|
数据采集 机器学习/深度学习 算法框架/工具
Python:现代编程的瑞士军刀
Python:现代编程的瑞士军刀
191 104

推荐镜像

更多