序列化框架——protoBuff

本文介绍如何使用Protobuf进行序列化和反序列化操作。包括Maven依赖配置、下载Protobuf工具、定义.proto文件、编译生成Java文件及在网络通信中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、maven依赖:                

                <dependency>
			<groupId>com.google.protobuf</groupId>
			<artifactId>protobuf-java</artifactId>
			<version>3.5.1</version>
		</dependency>

2、下载protobuff工具(进行编译proto文件,生成java文件),下载地址:https://github.com/google/protobuf/releases,选择自己需要的。

 windows环境下,下载protoc-3.5.1-win32.zip,如下图

解压,后面用bin目录中有protoc.exe文件编译proto文件,生成java文件



3、定义person.proto文件

syntax = "proto3";

option java_package = "com.java.protobuff";
option java_outer_classname = "PersonFactory";

message Person{
	int32 id = 1;
	string name = 2;
	int32 age = 3;
	Addr addr = 4;
}

message Addr{
	string contry = 1;
	string city = 2;
}

proto文件编写规则参考:

Protobuf使用手册

Protobuf学习 - 入门

4、然后用命令编译生成java文件,命令如下:

protoc --java_out=D:\eclipse_workspace\protobuff-hl\src\main\java ./person.proto

解释一下:protoc就是bin目录中有protoc.exe文件

                --java_out=表示生成的java文件存放的路径

                最后的参数./person.proto,表示定义文件

生成的java文件为PersonFactory,这个文件很复杂,在这里就不细讲了,很重要自己必须看一下。

根据协议已经生成好对象的工厂java,后面开始用这个工厂生成符合协议的对象,然后进行序列化和反序列化操作。

5、编码使用protobuff

下面模拟网络socket通信过程中使用protobuff进行序列化和反序列化的场景:

先上一个图,整体看一下:


具体怎么使用在下面两个文件中:

Client.java:

package com.java.protobuff;

import java.net.Socket;

import com.java.protobuff.PersonFactory.Addr;
import com.java.protobuff.PersonFactory.Person;

public class Client {
	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("127.0.0.1",3030);  
        
        Person.Builder person = Person.newBuilder();  
          
        Addr.Builder addr = Addr.newBuilder();  
        addr.setContry("china").setCity("shenzhen");  
          
        person.setId(1).setAge(12).setName("ccf");  
        person.setAddr(addr);  
          
        byte[] messageBody = person.build().toByteArray();  
      
        int headerLen = 1;  
        byte[] message = new byte[headerLen+messageBody.length];  
        message[0] = (byte)messageBody.length;  
        System.arraycopy(messageBody, 0,  message, 1, messageBody.length);  
        System.out.println("msg len:"+message.length);  
        socket.getOutputStream().write(message);  
	}
}

Server.java:

package com.java.protobuff;

import java.net.ServerSocket;
import java.net.Socket;

import com.java.protobuff.PersonFactory.Person;

public class Server {

	public static void main(String[] args) throws Exception{
		ServerSocket serverSock = new ServerSocket(3030);  
		while(true){  
			Socket sock = serverSock.accept();  
			byte[] msg = new byte[256];  
			sock.getInputStream().read(msg);  
			int msgBodyLen = msg[0];  
			System.out.println("msg body len:"+msgBodyLen);  
			byte[] msgbody = new byte[msgBodyLen];  
			System.arraycopy(msg, 1, msgbody, 0, msgBodyLen);  

			Person person = Person.parseFrom(msgbody);  

			System.out.println("Receive:");  
			System.out.println(person);

		}
	}

}

6、大致说一下protostuf不太好的地方,个人见解,供参考:

1、需要定义proto文件

2、然后需要使用protoc.exe编译定义的proto文件,生成对象的工厂类

3、工厂类比较复杂,使用的时候有点繁琐


最后说明:这篇博文是入门级的,让你体验一下protobuff,了解怎么使用,差不多了就去深入研究细节,全面掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值