google protobuf
下载工具
https://github.com/protocolbuffers/protobuf/releases/tag/v3.13.0
由于我使用的是windowsX64,我选择win64版本
下载后,解压将bin目录放入环境变量里面
编写proto文件
新建文件AddressBook.proto文件
syntax = "proto2";
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
在当前目录运行改命令,注意java_out好像不支持绝对路径,支持相对路径
$ protoc --java_out=. addressbook.proto
项目中实战
protoc --java_out=../src/main/java addressbook.proto
# 新建文件,注意需要修改proto里面的文件里面的package和实际当中的一直
# 说实话,这就是和那个tk-mybatis一样,自动生成文件
生成好后,打开文件AddressBookProtos.java文件,是被final修饰的,我们不要修改,还缺一些东西,需要我们引入jar包
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.12.4</version>
</dependency>
我们来两个案例,一个写文件一个读文件
public class WriteValueToFile {
public static void main(String[] args) throws IOException {
AddressBookProtos.AddressBook addressBook = AddressBookProtos.AddressBook.newBuilder()
.mergeFrom(new FileInputStream("addressBook.txt"))
.addPeople(AddressBookProtos.Person.newBuilder()
.setEmail("adios@qq.com")
.setId(1025)
.setName("adios")
.addPhones(AddressBookProtos.Person.PhoneNumber.newBuilder()
.setNumber("15851741817")
.setType(AddressBookProtos.Person.PhoneType.HOME)
.build())
.build())
.build();
FileOutputStream fos = new FileOutputStream("addressBook.txt");
addressBook.writeTo(fos);
fos.close();
}
}
public class ReadValueFromFile {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("addressBook.txt");
AddressBookProtos.AddressBook addressBook = AddressBookProtos.AddressBook.parseFrom(fis);
List<AddressBookProtos.Person> peopleList = addressBook.getPeopleList();
for (AddressBookProtos.Person person : peopleList) {
System.out.println("personal information " + person.getId() + " " + person.getEmail() + " " + person.getName());
for (AddressBookProtos.Person.PhoneNumber phone : person.getPhonesList()) {
System.out.println("phone " + phone.getNumber() + " " + phone.getType().getValueDescriptor());
}
}
}
}
讲讲为什么学习这个
首先在学习netty过程中,多次碰到这个。今天看别人项目,正好看见这个,学习了一下
官方文档:https://developers.google.com/protocol-buffers/docs/javatutorial
文档里面讲了:为什么使用这个google protocol
- Use Java Serialization. This is the default approach since it’s built into the language, but it has a host of well-known problems (see Effective Java, by Josh Bloch pp. 213), and also doesn’t work very well if you need to share data with applications written in C++ or Python.
- You can invent an ad-hoc way to encode the data items into a single string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and flexible approach, although it does require writing one-off encoding and parsing code, and the parsing imposes a small run-time cost. This works best for encoding very simple data.
- Serialize the data to XML. This approach can be very attractive since XML is (sort of) human readable and there are binding libraries for lots of languages. This can be a good choice if you want to share data with other applications/projects. However, XML is notoriously space intensive, and encoding/decoding it can impose a huge performance penalty on applications. Also, navigating an XML DOM tree is considerably more complicated than navigating simple fields in a class normally would be.
- java的序列化没办法和其他语言共享数据
- 如果是简单的,我们可以设计一个规则,:分割。这对简单数据编码是有效的
- 使用xml,但是xml会占用大量空间
文中并没有比较json相关的.