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

目录
打赏
0
0
0
0
58
分享
相关文章
java常用数据判空、比较和类型转换
本文介绍了Java开发中常见的数据处理技巧,包括数据判空、数据比较和类型转换。详细讲解了字符串、Integer、对象、List、Map、Set及数组的判空方法,推荐使用工具类如StringUtils、Objects等。同时,讨论了基本数据类型与引用数据类型的比较方法,以及自动类型转换和强制类型转换的规则。最后,提供了数值类型与字符串互相转换的具体示例。
136 3
Java和Python在企业中的应用情况
Java和Python在企业中的应用情况
111 7
Java爬虫获取微店快递费用item_fee API接口数据实现
本文介绍如何使用Java开发爬虫程序,通过微店API接口获取商品快递费用(item_fee)数据。主要内容包括:微店API接口的使用方法、Java爬虫技术背景、需求分析和技术选型。具体实现步骤为:发送HTTP请求获取数据、解析JSON格式的响应并提取快递费用信息,最后将结果存储到本地文件中。文中还提供了完整的代码示例,并提醒开发者注意授权令牌、接口频率限制及数据合法性等问题。
|
22天前
|
使用Java和Spring Data构建数据访问层
本文介绍了如何使用 Java 和 Spring Data 构建数据访问层的完整过程。通过创建实体类、存储库接口、服务类和控制器类,实现了对数据库的基本操作。这种方法不仅简化了数据访问层的开发,还提高了代码的可维护性和可读性。通过合理使用 Spring Data 提供的功能,可以大幅提升开发效率。
62 21
深潜数据海洋:Java文件读写全面解析与实战指南
通过本文的详细解析与实战示例,您可以系统地掌握Java中各种文件读写操作,从基本的读写到高效的NIO操作,再到文件复制、移动和删除。希望这些内容能够帮助您在实际项目中处理文件数据,提高开发效率和代码质量。
11 0
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
54 7
【潜意识Java】深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
80 1
|
1月前
|
java怎么统计每个项目下的每个类别的数据
通过本文,我们详细介绍了如何在Java中统计每个项目下的每个类别的数据,包括数据模型设计、数据存储和统计方法。通过定义 `Category`和 `Project`类,并使用 `ProjectManager`类进行管理,可以轻松实现项目和类别的数据统计。希望本文能够帮助您理解和实现类似的统计需求。
107 17
|
3月前
|
Java|如何用一个统一结构接收成员名称不固定的数据
本文介绍了一种 Java 中如何用一个统一结构接收成员名称不固定的数据的方法。
54 3
在比较Java和Python哪个更易学
在比较Java和Python哪个更易学
54 4

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等