初识
Protocol Buff是谷歌推出的一种序列化协议. 而Java序列化协议也是一种协议.
两者的目的是, 将对象序列化成字节数组, 或者说是二进制数据, 那么他们之间有什么差异呢.
proto对象
要使用PB, 我们需要定义一个proto对象, 其支持的数据类型如下:
Protobuf定义了一套基本数据类型。几乎都可以映射到C++Java等语言的基础数据类型.
protobuf 数据类型 |
描述 |
打包 |
C++语言映射 |
bool |
布尔类型 |
1字节 |
bool |
double |
64位浮点数 |
N |
double |
float |
32为浮点数 |
N |
float |
int32 |
32位整数、 |
N |
int |
uin32 |
无符号32位整数 |
N |
unsigned int |
int64 |
64位整数 |
N |
__int64 |
uint64 |
64为无符号整 |
N |
unsigned __int64 |
sint32 |
32位整数,处理负数效率更高 |
N |
int32 |
sing64 |
64位整数 处理负数效率更高 |
N |
__int64 |
fixed32 |
32位无符号整数 |
4 |
unsigned int32 |
fixed64 |
64位无符号整数 |
8 |
unsigned __int64 |
sfixed32 |
32位整数、能以更高的效率处理负数 |
4 |
unsigned int32 |
sfixed64 |
64为整数 |
8 |
unsigned __int64 |
string |
只能处理 ASCII字符 |
N |
std::string |
bytes |
用于处理多字节的语言字符、如中文 |
N |
std::string |
enum |
可以包含一个用户自定义的枚举类型uint32 |
N(uint32) |
enum |
message |
可以包含一个用户自定义的消息类型 |
N |
object of class |
proto对象结构类似于java的class, 在同一个module里, 定义了两个类, PBPlayer 和 PBResource, 各自拥有一些成员变量.
1 option java_package = "com.proto"; 2 option java_outer_classname = "PlayerModule"; 3 4 message PBPlayer{ 5 required int64 playerId = 1; 6 7 required int32 age = 2; 8 9 required string name = 3; 10 11 repeated int32 skills = 4; 12 } 13 14 message PBResource{ 15 required int64 gold = 1; 16 17 required int32 energy = 2; 18 }
然后用protoc.exe将proto对象转为java对象, 打开cmd, 运行如下命令:
1 protoc ./proto/*.proto --java_out=./src
生成的java对象比较庞大, 我们不需要细究里面代码, 直接调用即可.
1 // Generated by the protocol buffer compiler. DO NOT EDIT! 2 // source: proto/player.proto 3 4 package com.proto; 5 6 public final class PlayerModule { 7 private PlayerModule() {} 8 public static void registerAllExtensions( 9 com.google.protobuf.ExtensionRegistry registry) { 10 } 11 public interface PBPlayerOrBuilder 12 extends com.google.protobuf.MessageOrBuilder { 13 14 // required int64 playerId = 1; 15 boolean hasPlayerId(); 16 long getPlayerId(); 17 18 // required int32 age = 2; 19 boolean hasAge(); 20 int getAge(); 21 22 // required string name = 3; 23 boolean hasName(); 24 String getName(); 25 26 // repeated int32 skills = 4; 27 java.util.List<java.lang.Integer> getSkillsList(); 28 int getSkillsCount(); 29 int getSkills(int index); 30 } 31 public static final class PBPlayer extends 32 com.google.protobuf.GeneratedMessage 33 implements PBPlayerOrBuilder { 34 // Use PBPlayer.newBuilder() to construct. 35 private PBPlayer(Builder builder) { 36 super(builder); 37 } 38 private PBPlayer(boolean noInit) {} 39 40 private static final PBPlayer defaultInstance; 41 public static PBPlayer getDefaultInstance() { 42 return defaultInstance; 43 } 44 45 public PBPlayer getDefaultInstanceForType() { 46 return defaultInstance; 47 } 48 49 public static final com.google.protobuf.Descriptors.Descriptor 50 getDescriptor() { 51 return com.proto.PlayerModule.internal_static_PBPlayer_descriptor; 52 } 53 54 protected com.google.protobuf.GeneratedMessage.FieldAccessorTable 55 internalGetFieldAccessorTable() { 56 return com.proto.PlayerModule.internal_static_PBPlayer_fieldAccessorTable; 57 } 58 59 private int bitField0_; 60 // required int64 playerId = 1; 61 public static final int PLAYERID_FIELD_NUMBER = 1; 62 private long playerId_; 63 public boolean hasPlayerId() { 64 return ((bitField0_ & 0x00000001) == 0x00000001); 65 } 66 public long getPlayerId() { 67 return playerId_; 68 } 69 70 // required int32 age = 2; 71 public static final int AGE_FIELD_NUMBER = 2; 72 private int age_; 73 public boolean hasAge() { 74 return ((bitField0_ & 0x00000002) == 0x00000002); 75 } 76 public int getAge() { 77 return age_; 78 } 79 80 // required string name = 3; 81 public static final int NAME_FIELD_NUMBER = 3; 82 private java.lang.Object name_; 83 public boolean hasName() { 84 return ((bitField0_ & 0x00000004) == 0x00000004); 85 } 86 public String getName() { 87 java.lang.Object ref = name_; 88 if (ref instanceof String) { 89 return (String) ref; 90 } else { 91 com.google.protobuf.ByteString bs = 92 (com.google.protobuf.ByteString) ref; 93 String s = bs.toStringUtf8(); 94 if (com.google.protobuf.Internal.isValidUtf8(bs)) { 95 name_ = s; 96 } 97 return s; 98 } 99 } 100 private com.google.protobuf.ByteString getNameBytes() { 101 java.lang.Object ref = name_; 102 if (ref instanceof String) { 103 com.google.protobuf.ByteString b = 104 com.google.protobuf.ByteString.copyFromUtf8((String) ref); 105 name_ = b; 106 return b; 107 } else { 108 return (com.google.protobuf.ByteString) ref; 109 } 110 } 111 112 // repeated int32 skills = 4; 113 public static final int SKILLS_FIELD_NUMBER = 4; 114 private java.util.List<java.lang.Integer> skills_; 115 public java.util.List<java.lang.Integer> 116 getSkillsList() { 117 return skills_; 118 } 119 public int getSkillsCount() { 120 return skills_.size(); 121 } 122 public int getSkills(int index) { 123 return skills_.get(index); 124 } 125 126 private void initFields() { 127 playerId_ = 0L; 128 age_ = 0; 129 name_ = ""; 130 skills_ = java.util.Collections.emptyList();; 131 } 132 private byte memoizedIsInitialized = -1; 133 public final boolean isInitialized() { 134 byte isInitialized = memoizedIsInitialized; 135 if (isInitialized != -1) return isInitialized == 1; 136 137 if (!hasPlayerId()) { 138 memoizedIsInitialized = 0; 139 return false; 140 } 141 if (!hasAge()) { 142 memoizedIsInitialized = 0; 143 return false; 144 } 145 if (!hasName()) { 146 memoizedIsInitialized = 0; 147 return false; 148 } 149 memoizedIsInitialized = 1; 150 return true; 151 } 152 153 public void writeTo(com.google.protobuf.CodedOutputStream output) 154 throws java.io.IOException { 155 getSerializedSize(); 156 if (((bitField0_ & 0x00000001) == 0x00000001)) { 157 output.writeInt64(1, playerId_); 158 } 159 if (((bitField0_ & 0x00000002) == 0x00000002)) { 160 output.writeInt32(2, age_); 161 } 162 if (((bitField0_ & 0x00000004) == 0x00000004)) { 163 output.writeBytes(3, getNameBytes()); 164 } 165 for (int i = 0; i < skills_.size(); i++) { 166 output.writeInt32(4, skills_.get(i)); 167 } 168 getUnknownFields().writeTo(output); 169 } 170 171 private int memoizedSerializedSize = -1; 172 public int getSerializedSize() { 173 int size = memoizedSerializedSize; 174 if (size != -1) return size; 175 176 size = 0; 177 if (((bitField0_ & 0x00000001) == 0x00000001)) { 178 size += com.google.protobuf.CodedOutputStream 179 .computeInt64Size(1, playerId_); 180 } 181 if (((bitField0_ & 0x00000002) == 0x00000002)) { 182 size += com.google.protobuf.CodedOutputStream 183 .computeInt32Size(2, age_); 184 } 185 if (((bitField0_ & 0x00000004) == 0x00000004)) { 186 size += com.google.protobuf.CodedOutputStream 187 .computeBytesSize(3, getNameBytes()); 188 } 189 { 190 int dataSize = 0; 191 for (int i = 0; i < skills_.size(); i++) { 192 dataSize += com.google.protobuf.CodedOutputStream 193 .computeInt32SizeNoTag(skills_.get(i)); 194 } 195 size += dataSize; 196 size += 1 * getSkillsList().size(); 197 } 198 size += getUnknownFields().getSerializedSize(); 199 memoizedSerializedSize = size; 200 return size; 201 } 202 203 private static final long serialVersionUID = 0L; 204 @java.lang.Override 205 protected java.lang.Object writeReplace() 206 throws java.io.ObjectStreamException { 207 return super.writeReplace(); 208 } 209 210 public static com.proto.PlayerModule.PBPlayer parseFrom( 211 com.google.protobuf.ByteString data) 212 throws com.google.protobuf.InvalidProtocolBufferException { 213 return newBuilder().mergeFrom(data).buildParsed(); 214 } 215 public static com.proto.PlayerModule.PBPlayer parseFrom( 216 com.google.protobuf.ByteString data, 217 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 218 throws com.google.protobuf.InvalidProtocolBufferException { 219 return newBuilder().mergeFrom(data, extensionRegistry) 220 .buildParsed(); 221 } 222 public static com.proto.PlayerModule.PBPlayer parseFrom(byte[] data) 223 throws com.google.protobuf.InvalidProtocolBufferException { 224 return newBuilder().mergeFrom(data).buildParsed(); 225 } 226 public static com.proto.PlayerModule.PBPlayer parseFrom( 227 byte[] data, 228 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 229 throws com.google.protobuf.InvalidProtocolBufferException { 230 return newBuilder().mergeFrom(data, extensionRegistry) 231 .buildParsed(); 232 } 233 public static com.proto.PlayerModule.PBPlayer parseFrom(java.io.InputStream input) 234 throws java.io.IOException { 235 return newBuilder().mergeFrom(input).buildParsed(); 236 } 237 public static com.proto.PlayerModule.PBPlayer parseFrom( 238 java.io.InputStream input, 239 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 240 throws java.io.IOException { 241 return newBuilder().mergeFrom(input, extensionRegistry) 242 .buildParsed(); 243 } 244 public static com.proto.PlayerModule.PBPlayer parseDelimitedFrom(java.io.InputStream input) 245 throws java.io.IOException { 246 Builder builder = newBuilder(); 247 if (builder.mergeDelimitedFrom(input)) { 248 return builder.buildParsed(); 249 } else { 250 return null; 251 } 252 } 253 public static com.proto.PlayerModule.PBPlayer parseDelimitedFrom( 254 java.io.InputStream input, 255 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 256 throws java.io.IOException { 257 Builder builder = newBuilder(); 258 if (builder.mergeDelimitedFrom(input, extensionRegistry)) { 259 return builder.buildParsed(); 260 } else { 261 return null; 262 } 263 } 264 public static com.proto.PlayerModule.PBPlayer parseFrom( 265 com.google.protobuf.CodedInputStream input) 266 throws java.io.IOException { 267 return newBuilder().mergeFrom(input).buildParsed(); 268 } 269 public static com.proto.PlayerModule.PBPlayer parseFrom( 270 com.google.protobuf.CodedInputStream input, 271 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 272 throws java.io.IOException { 273 return newBuilder().mergeFrom(input, extensionRegistry) 274 .buildParsed(); 275 } 276 277 public static Builder newBuilder() { return Builder.create(); } 278 public Builder newBuilderForType() { return newBuilder(); } 279 public static Builder newBuilder(com.proto.PlayerModule.PBPlayer prototype) { 280 return newBuilder().mergeFrom(prototype); 281 } 282 public Builder toBuilder() { return newBuilder(this); } 283 284 @java.lang.Override 285 protected Builder newBuilderForType( 286 com.google.protobuf.GeneratedMessage.BuilderParent parent) { 287 Builder builder = new Builder(parent); 288 return builder; 289 } 290 public static final class Builder extends 291 com.google.protobuf.GeneratedMessage.Builder<Builder> 292 implements com.proto.PlayerModule.PBPlayerOrBuilder { 293 public static final com.google.protobuf.Descriptors.Descriptor 294 getDescriptor() { 295 return com.proto.PlayerModule.internal_static_PBPlayer_descriptor; 296 } 297 298 protected com.google.protobuf.GeneratedMessage.FieldAccessorTable 299 internalGetFieldAccessorTable() { 300 return com.proto.PlayerModule.internal_static_PBPlayer_fieldAccessorTable; 301 } 302 303 // Construct using com.proto.PlayerModule.PBPlayer.newBuilder() 304 private Builder() { 305 maybeForceBuilderInitialization(); 306 } 307 308 private Builder(BuilderParent parent) { 309 super(parent); 310 maybeForceBuilderInitialization(); 311 } 312 private void maybeForceBuilderInitialization() { 313 if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { 314 } 315 } 316 private static Builder create() { 317 return new Builder(); 318 } 319 320 public Builder clear() { 321 super.clear(); 322 playerId_ = 0L; 323 bitField0_ = (bitField0_ & ~0x00000001); 324 age_ = 0; 325 bitField0_ = (bitField0_ & ~0x00000002); 326 name_ = ""; 327 bitField0_ = (bitField0_ & ~0x00000004); 328 skills_ = java.util.Collections.emptyList();; 329 bitField0_ = (bitField0_ & ~0x00000008); 330 return this; 331 } 332 333 public Builder clone() { 334 return create().mergeFrom(buildPartial()); 335 } 336 337 public com.google.protobuf.Descriptors.Descriptor 338 getDescriptorForType() { 339 return com.proto.PlayerModule.PBPlayer.getDescriptor(); 340 } 341 342 public com.proto.PlayerModule.PBPlayer getDefaultInstanceForType() { 343 return com.proto.PlayerModule.PBPlayer.getDefaultInstance(); 344 } 345 346 public com.proto.PlayerModule.PBPlayer build() { 347 com.proto.PlayerModule.PBPlayer result = buildPartial(); 348 if (!result.isInitialized()) { 349 throw newUninitializedMessageException(result); 350 } 351 return result; 352 } 353 354 private com.proto.PlayerModule.PBPlayer buildParsed() 355 throws com.google.protobuf.InvalidProtocolBufferException { 356 com.proto.PlayerModule.PBPlayer result = buildPartial(); 357 if (!result.isInitialized()) { 358 throw newUninitializedMessageException( 359 result).asInvalidProtocolBufferException(); 360 } 361 return result; 362 } 363 364 public com.proto.PlayerModule.PBPlayer buildPartial() { 365 com.proto.PlayerModule.PBPlayer result = new com.proto.PlayerModule.PBPlayer(this); 366 int from_bitField0_ = bitField0_; 367 int to_bitField0_ = 0; 368 if (((from_bitField0_ & 0x00000001) == 0x00000001)) { 369 to_bitField0_ |= 0x00000001; 370 } 371 result.playerId_ = playerId_; 372 if (((from_bitField0_ & 0x00000002) == 0x00000002)) { 373 to_bitField0_ |= 0x00000002; 374 } 375 result.age_ = age_; 376 if (((from_bitField0_ & 0x00000004) == 0x00000004)) { 377 to_bitField0_ |= 0x00000004; 378 } 379 result.name_ = name_; 380 if (((bitField0_ & 0x00000008) == 0x00000008)) { 381 skills_ = java.util.Collections.unmodifiableList(skills_); 382 bitField0_ = (bitField0_ & ~0x00000008); 383 } 384 result.skills_ = skills_; 385 result.bitField0_ = to_bitField0_; 386 onBuilt(); 387 return result; 388 } 389 390 public Builder mergeFrom(com.google.protobuf.Message other) { 391 if (other instanceof com.proto.PlayerModule.PBPlayer) { 392 return mergeFrom((com.proto.PlayerModule.PBPlayer)other); 393 } else { 394 super.mergeFrom(other); 395 return this; 396 } 397 } 398 399 public Builder mergeFrom(com.proto.PlayerModule.PBPlayer other) { 400 if (other == com.proto.PlayerModule.PBPlayer.getDefaultInstance()) return this; 401 if (other.hasPlayerId()) { 402 setPlayerId(other.getPlayerId()); 403 } 404 if (other.hasAge()) { 405 setAge(other.getAge()); 406 } 407 if (other.hasName()) { 408 setName(other.getName()); 409 } 410 if (!other.skills_.isEmpty()) { 411 if (skills_.isEmpty()) { 412 skills_ = other.skills_; 413 bitField0_ = (bitField0_ & ~0x00000008); 414 } else { 415 ensureSkillsIsMutable(); 416 skills_.addAll(other.skills_); 417 } 418 onChanged(); 419 } 420 this.mergeUnknownFields(other.getUnknownFields()); 421 return this; 422 } 423 424 public final boolean isInitialized() { 425 if (!hasPlayerId()) { 426 427 return false; 428 } 429 if (!hasAge()) { 430 431 return false; 432 } 433 if (!hasName()) { 434 435 return false; 436 } 437 return true; 438 } 439 440 public Builder mergeFrom( 441 com.google.protobuf.CodedInputStream input, 442 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 443 throws java.io.IOException { 444 com.google.protobuf.UnknownFieldSet.Builder unknownFields = 445 com.google.protobuf.UnknownFieldSet.newBuilder( 446 this.getUnknownFields()); 447 while (true) { 448 int tag = input.readTag(); 449 switch (tag) { 450 case 0: 451 this.setUnknownFields(unknownFields.build()); 452 onChanged(); 453 return this; 454 default: { 455 if (!parseUnknownField(input, unknownFields, 456 extensionRegistry, tag)) { 457 this.setUnknownFields(unknownFields.build()); 458 onChanged(); 459 return this; 460 } 461 break; 462 } 463 case 8: { 464 bitField0_ |= 0x00000001; 465 playerId_ = input.readInt64(); 466 break; 467 } 468 case 16: { 469 bitField0_ |= 0x00000002; 470 age_ = input.readInt32(); 471 break; 472 } 473 case 26: { 474 bitField0_ |= 0x00000004; 475 name_ = input.readBytes(); 476 break; 477 } 478 case 32: { 479 ensureSkillsIsMutable(); 480 skills_.add(input.readInt32()); 481 break; 482 } 483 case 34: { 484 int length = input.readRawVarint32(); 485 int limit = input.pushLimit(length); 486 while (input.getBytesUntilLimit() > 0) { 487 addSkills(input.readInt32()); 488 } 489 input.popLimit(limit); 490 break; 491 } 492 } 493 } 494 } 495 496 private int bitField0_; 497 498 // required int64 playerId = 1; 499 private long playerId_ ; 500 public boolean hasPlayerId() { 501 return ((bitField0_ & 0x00000001) == 0x00000001); 502 } 503 public long getPlayerId() { 504 return playerId_; 505 } 506 public Builder setPlayerId(long value) { 507 bitField0_ |= 0x00000001; 508 playerId_ = value; 509 onChanged(); 510 return this; 511 } 512 public Builder clearPlayerId() { 513 bitField0_ = (bitField0_ & ~0x00000001); 514 playerId_ = 0L; 515 onChanged(); 516 return this; 517 } 518 519 // required int32 age = 2; 520 private int age_ ; 521 public boolean hasAge() { 522 return ((bitField0_ & 0x00000002) == 0x00000002); 523 } 524 public int getAge() { 525 return age_; 526 } 527 public Builder setAge(int value) { 528 bitField0_ |= 0x00000002; 529 age_ = value; 530 onChanged(); 531 return this; 532 } 533 public Builder clearAge() { 534 bitField0_ = (bitField0_ & ~0x00000002); 535 age_ = 0; 536 onChanged(); 537 return this; 538 } 539 540 // required string name = 3; 541 private java.lang.Object name_ = ""; 542 public boolean hasName() { 543 return ((bitField0_ & 0x00000004) == 0x00000004); 544 } 545 public String getName() { 546 java.lang.Object ref = name_; 547 if (!(ref instanceof String)) { 548 String s = ((com.google.protobuf.ByteString) ref).toStringUtf8(); 549 name_ = s; 550 return s; 551 } else { 552 return (String) ref; 553 } 554 } 555 public Builder setName(String value) { 556 if (value == null) { 557 throw new NullPointerException(); 558 } 559 bitField0_ |= 0x00000004; 560 name_ = value; 561 onChanged(); 562 return this; 563 } 564 public Builder clearName() { 565 bitField0_ = (bitField0_ & ~0x00000004); 566 name_ = getDefaultInstance().getName(); 567 onChanged(); 568 return this; 569 } 570 void setName(com.google.protobuf.ByteString value) { 571 bitField0_ |= 0x00000004; 572 name_ = value; 573 onChanged(); 574 } 575 576 // repeated int32 skills = 4; 577 private java.util.List<java.lang.Integer> skills_ = java.util.Collections.emptyList();; 578 private void ensureSkillsIsMutable() { 579 if (!((bitField0_ & 0x00000008) == 0x00000008)) { 580 skills_ = new java.util.ArrayList<java.lang.Integer>(skills_); 581 bitField0_ |= 0x00000008; 582 } 583 } 584 public java.util.List<java.lang.Integer> 585 getSkillsList() { 586 return java.util.Collections.unmodifiableList(skills_); 587 } 588 public int getSkillsCount() { 589 return skills_.size(); 590 } 591 public int getSkills(int index) { 592 return skills_.get(index); 593 } 594 public Builder setSkills( 595 int index, int value) { 596 ensureSkillsIsMutable(); 597 skills_.set(index, value); 598 onChanged(); 599 return this; 600 } 601 public Builder addSkills(int value) { 602 ensureSkillsIsMutable(); 603 skills_.add(value); 604 onChanged(); 605 return this; 606 } 607 public Builder addAllSkills( 608 java.lang.Iterable<? extends java.lang.Integer> values) { 609 ensureSkillsIsMutable(); 610 super.addAll(values, skills_); 611 onChanged(); 612 return this; 613 } 614 public Builder clearSkills() { 615 skills_ = java.util.Collections.emptyList();; 616 bitField0_ = (bitField0_ & ~0x00000008); 617 onChanged(); 618 return this; 619 } 620 621 // @@protoc_insertion_point(builder_scope:PBPlayer) 622 } 623 624 static { 625 defaultInstance = new PBPlayer(true); 626 defaultInstance.initFields(); 627 } 628 629 // @@protoc_insertion_point(class_scope:PBPlayer) 630 } 631 632 public interface PBResourceOrBuilder 633 extends com.google.protobuf.MessageOrBuilder { 634 635 // required int64 gold = 1; 636 boolean hasGold(); 637 long getGold(); 638 639 // required int32 energy = 2; 640 boolean hasEnergy(); 641 int getEnergy(); 642 } 643 public static final class PBResource extends 644 com.google.protobuf.GeneratedMessage 645 implements PBResourceOrBuilder { 646 // Use PBResource.newBuilder() to construct. 647 private PBResource(Builder builder) { 648 super(builder); 649 } 650 private PBResource(boolean noInit) {} 651 652 private static final PBResource defaultInstance; 653 public static PBResource getDefaultInstance() { 654 return defaultInstance; 655 } 656 657 public PBResource getDefaultInstanceForType() { 658 return defaultInstance; 659 } 660 661 public static final com.google.protobuf.Descriptors.Descriptor 662 getDescriptor() { 663 return com.proto.PlayerModule.internal_static_PBResource_descriptor; 664 } 665 666 protected com.google.protobuf.GeneratedMessage.FieldAccessorTable 667 internalGetFieldAccessorTable() { 668 return com.proto.PlayerModule.internal_static_PBResource_fieldAccessorTable; 669 } 670 671 private int bitField0_; 672 // required int64 gold = 1; 673 public static final int GOLD_FIELD_NUMBER = 1; 674 private long gold_; 675 public boolean hasGold() { 676 return ((bitField0_ & 0x00000001) == 0x00000001); 677 } 678 public long getGold() { 679 return gold_; 680 } 681 682 // required int32 energy = 2; 683 public static final int ENERGY_FIELD_NUMBER = 2; 684 private int energy_; 685 public boolean hasEnergy() { 686 return ((bitField0_ & 0x00000002) == 0x00000002); 687 } 688 public int getEnergy() { 689 return energy_; 690 } 691 692 private void initFields() { 693 gold_ = 0L; 694 energy_ = 0; 695 } 696 private byte memoizedIsInitialized = -1; 697 public final boolean isInitialized() { 698 byte isInitialized = memoizedIsInitialized; 699 if (isInitialized != -1) return isInitialized == 1; 700 701 if (!hasGold()) { 702 memoizedIsInitialized = 0; 703 return false; 704 } 705 if (!hasEnergy()) { 706 memoizedIsInitialized = 0; 707 return false; 708 } 709 memoizedIsInitialized = 1; 710 return true; 711 } 712 713 public void writeTo(com.google.protobuf.CodedOutputStream output) 714 throws java.io.IOException { 715 getSerializedSize(); 716 if (((bitField0_ & 0x00000001) == 0x00000001)) { 717 output.writeInt64(1, gold_); 718 } 719 if (((bitField0_ & 0x00000002) == 0x00000002)) { 720 output.writeInt32(2, energy_); 721 } 722 getUnknownFields().writeTo(output); 723 } 724 725 private int memoizedSerializedSize = -1; 726 public int getSerializedSize() { 727 int size = memoizedSerializedSize; 728 if (size != -1) return size; 729 730 size = 0; 731 if (((bitField0_ & 0x00000001) == 0x00000001)) { 732 size += com.google.protobuf.CodedOutputStream 733 .computeInt64Size(1, gold_); 734 } 735 if (((bitField0_ & 0x00000002) == 0x00000002)) { 736 size += com.google.protobuf.CodedOutputStream 737 .computeInt32Size(2, energy_); 738 } 739 size += getUnknownFields().getSerializedSize(); 740 memoizedSerializedSize = size; 741 return size; 742 } 743 744 private static final long serialVersionUID = 0L; 745 @java.lang.Override 746 protected java.lang.Object writeReplace() 747 throws java.io.ObjectStreamException { 748 return super.writeReplace(); 749 } 750 751 public static com.proto.PlayerModule.PBResource parseFrom( 752 com.google.protobuf.ByteString data) 753 throws com.google.protobuf.InvalidProtocolBufferException { 754 return newBuilder().mergeFrom(data).buildParsed(); 755 } 756 public static com.proto.PlayerModule.PBResource parseFrom( 757 com.google.protobuf.ByteString data, 758 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 759 throws com.google.protobuf.InvalidProtocolBufferException { 760 return newBuilder().mergeFrom(data, extensionRegistry) 761 .buildParsed(); 762 } 763 public static com.proto.PlayerModule.PBResource parseFrom(byte[] data) 764 throws com.google.protobuf.InvalidProtocolBufferException { 765 return newBuilder().mergeFrom(data).buildParsed(); 766 } 767 public static com.proto.PlayerModule.PBResource parseFrom( 768 byte[] data, 769 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 770 throws com.google.protobuf.InvalidProtocolBufferException { 771 return newBuilder().mergeFrom(data, extensionRegistry) 772 .buildParsed(); 773 } 774 public static com.proto.PlayerModule.PBResource parseFrom(java.io.InputStream input) 775 throws java.io.IOException { 776 return newBuilder().mergeFrom(input).buildParsed(); 777 } 778 public static com.proto.PlayerModule.PBResource parseFrom( 779 java.io.InputStream input, 780 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 781 throws java.io.IOException { 782 return newBuilder().mergeFrom(input, extensionRegistry) 783 .buildParsed(); 784 } 785 public static com.proto.PlayerModule.PBResource parseDelimitedFrom(java.io.InputStream input) 786 throws java.io.IOException { 787 Builder builder = newBuilder(); 788 if (builder.mergeDelimitedFrom(input)) { 789 return builder.buildParsed(); 790 } else { 791 return null; 792 } 793 } 794 public static com.proto.PlayerModule.PBResource parseDelimitedFrom( 795 java.io.InputStream input, 796 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 797 throws java.io.IOException { 798 Builder builder = newBuilder(); 799 if (builder.mergeDelimitedFrom(input, extensionRegistry)) { 800 return builder.buildParsed(); 801 } else { 802 return null; 803 } 804 } 805 public static com.proto.PlayerModule.PBResource parseFrom( 806 com.google.protobuf.CodedInputStream input) 807 throws java.io.IOException { 808 return newBuilder().mergeFrom(input).buildParsed(); 809 } 810 public static com.proto.PlayerModule.PBResource parseFrom( 811 com.google.protobuf.CodedInputStream input, 812 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 813 throws java.io.IOException { 814 return newBuilder().mergeFrom(input, extensionRegistry) 815 .buildParsed(); 816 } 817 818 public static Builder newBuilder() { return Builder.create(); } 819 public Builder newBuilderForType() { return newBuilder(); } 820 public static Builder newBuilder(com.proto.PlayerModule.PBResource prototype) { 821 return newBuilder().mergeFrom(prototype); 822 } 823 public Builder toBuilder() { return newBuilder(this); } 824 825 @java.lang.Override 826 protected Builder newBuilderForType( 827 com.google.protobuf.GeneratedMessage.BuilderParent parent) { 828 Builder builder = new Builder(parent); 829 return builder; 830 } 831 public static final class Builder extends 832 com.google.protobuf.GeneratedMessage.Builder<Builder> 833 implements com.proto.PlayerModule.PBResourceOrBuilder { 834 public static final com.google.protobuf.Descriptors.Descriptor 835 getDescriptor() { 836 return com.proto.PlayerModule.internal_static_PBResource_descriptor; 837 } 838 839 protected com.google.protobuf.GeneratedMessage.FieldAccessorTable 840 internalGetFieldAccessorTable() { 841 return com.proto.PlayerModule.internal_static_PBResource_fieldAccessorTable; 842 } 843 844 // Construct using com.proto.PlayerModule.PBResource.newBuilder() 845 private Builder() { 846 maybeForceBuilderInitialization(); 847 } 848 849 private Builder(BuilderParent parent) { 850 super(parent); 851 maybeForceBuilderInitialization(); 852 } 853 private void maybeForceBuilderInitialization() { 854 if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { 855 } 856 } 857 private static Builder create() { 858 return new Builder(); 859 } 860 861 public Builder clear() { 862 super.clear(); 863 gold_ = 0L; 864 bitField0_ = (bitField0_ & ~0x00000001); 865 energy_ = 0; 866 bitField0_ = (bitField0_ & ~0x00000002); 867 return this; 868 } 869 870 public Builder clone() { 871 return create().mergeFrom(buildPartial()); 872 } 873 874 public com.google.protobuf.Descriptors.Descriptor 875 getDescriptorForType() { 876 return com.proto.PlayerModule.PBResource.getDescriptor(); 877 } 878 879 public com.proto.PlayerModule.PBResource getDefaultInstanceForType() { 880 return com.proto.PlayerModule.PBResource.getDefaultInstance(); 881 } 882 883 public com.proto.PlayerModule.PBResource build() { 884 com.proto.PlayerModule.PBResource result = buildPartial(); 885 if (!result.isInitialized()) { 886 throw newUninitializedMessageException(result); 887 } 888 return result; 889 } 890 891 private com.proto.PlayerModule.PBResource buildParsed() 892 throws com.google.protobuf.InvalidProtocolBufferException { 893 com.proto.PlayerModule.PBResource result = buildPartial(); 894 if (!result.isInitialized()) { 895 throw newUninitializedMessageException( 896 result).asInvalidProtocolBufferException(); 897 } 898 return result; 899 } 900 901 public com.proto.PlayerModule.PBResource buildPartial() { 902 com.proto.PlayerModule.PBResource result = new com.proto.PlayerModule.PBResource(this); 903 int from_bitField0_ = bitField0_; 904 int to_bitField0_ = 0; 905 if (((from_bitField0_ & 0x00000001) == 0x00000001)) { 906 to_bitField0_ |= 0x00000001; 907 } 908 result.gold_ = gold_; 909 if (((from_bitField0_ & 0x00000002) == 0x00000002)) { 910 to_bitField0_ |= 0x00000002; 911 } 912 result.energy_ = energy_; 913 result.bitField0_ = to_bitField0_; 914 onBuilt(); 915 return result; 916 } 917 918 public Builder mergeFrom(com.google.protobuf.Message other) { 919 if (other instanceof com.proto.PlayerModule.PBResource) { 920 return mergeFrom((com.proto.PlayerModule.PBResource)other); 921 } else { 922 super.mergeFrom(other); 923 return this; 924 } 925 } 926 927 public Builder mergeFrom(com.proto.PlayerModule.PBResource other) { 928 if (other == com.proto.PlayerModule.PBResource.getDefaultInstance()) return this; 929 if (other.hasGold()) { 930 setGold(other.getGold()); 931 } 932 if (other.hasEnergy()) { 933 setEnergy(other.getEnergy()); 934 } 935 this.mergeUnknownFields(other.getUnknownFields()); 936 return this; 937 } 938 939 public final boolean isInitialized() { 940 if (!hasGold()) { 941 942 return false; 943 } 944 if (!hasEnergy()) { 945 946 return false; 947 } 948 return true; 949 } 950 951 public Builder mergeFrom( 952 com.google.protobuf.CodedInputStream input, 953 com.google.protobuf.ExtensionRegistryLite extensionRegistry) 954 throws java.io.IOException { 955 com.google.protobuf.UnknownFieldSet.Builder unknownFields = 956 com.google.protobuf.UnknownFieldSet.newBuilder( 957 this.getUnknownFields()); 958 while (true) { 959 int tag = input.readTag(); 960 switch (tag) { 961 case 0: 962 this.setUnknownFields(unknownFields.build()); 963 onChanged(); 964 return this; 965 default: { 966 if (!parseUnknownField(input, unknownFields, 967 extensionRegistry, tag)) { 968 this.setUnknownFields(unknownFields.build()); 969 onChanged(); 970 return this; 971 } 972 break; 973 } 974 case 8: { 975 bitField0_ |= 0x00000001; 976 gold_ = input.readInt64(); 977 break; 978 } 979 case 16: { 980 bitField0_ |= 0x00000002; 981 energy_ = input.readInt32(); 982 break; 983 } 984 } 985 } 986 } 987 988 private int bitField0_; 989 990 // required int64 gold = 1; 991 private long gold_ ; 992 public boolean hasGold() { 993 return ((bitField0_ & 0x00000001) == 0x00000001); 994 } 995 public long getGold() { 996 return gold_; 997 } 998 public Builder setGold(long value) { 999 bitField0_ |= 0x00000001; 1000 gold_ = value; 1001 onChanged(); 1002 return this; 1003 } 1004 public Builder clearGold() { 1005 bitField0_ = (bitField0_ & ~0x00000001); 1006 gold_ = 0L; 1007 onChanged(); 1008 return this; 1009 } 1010 1011 // required int32 energy = 2; 1012 private int energy_ ; 1013 public boolean hasEnergy() { 1014 return ((bitField0_ & 0x00000002) == 0x00000002); 1015 } 1016 public int getEnergy() { 1017 return energy_; 1018 } 1019 public Builder setEnergy(int value) { 1020 bitField0_ |= 0x00000002; 1021 energy_ = value; 1022 onChanged(); 1023 return this; 1024 } 1025 public Builder clearEnergy() { 1026 bitField0_ = (bitField0_ & ~0x00000002); 1027 energy_ = 0; 1028 onChanged(); 1029 return this; 1030 } 1031 1032 // @@protoc_insertion_point(builder_scope:PBResource) 1033 } 1034 1035 static { 1036 defaultInstance = new PBResource(true); 1037 defaultInstance.initFields(); 1038 } 1039 1040 // @@protoc_insertion_point(class_scope:PBResource) 1041 } 1042 1043 private static com.google.protobuf.Descriptors.Descriptor 1044 internal_static_PBPlayer_descriptor; 1045 private static 1046 com.google.protobuf.GeneratedMessage.FieldAccessorTable 1047 internal_static_PBPlayer_fieldAccessorTable; 1048 private static com.google.protobuf.Descriptors.Descriptor 1049 internal_static_PBResource_descriptor; 1050 private static 1051 com.google.protobuf.GeneratedMessage.FieldAccessorTable 1052 internal_static_PBResource_fieldAccessorTable; 1053 1054 public static com.google.protobuf.Descriptors.FileDescriptor 1055 getDescriptor() { 1056 return descriptor; 1057 } 1058 private static com.google.protobuf.Descriptors.FileDescriptor 1059 descriptor; 1060 static { 1061 java.lang.String[] descriptorData = { 1062 " 22proto/player.proto"G 10PBPlayer 22 20 10play" + 1063 "erId 30 01 02( 03 22 13 03age 30 02 02( 05 22 14 04name 30 03 02( 22 16 " + 1064 " 06skills 30 04 03( 05"* PBResource 22 14 04gold 30 01 02(" + 1065 " 03 22 16 06energy 30 02 02( 05B 31 com.protoB 14PlayerMo" + 1066 "dule" 1067 }; 1068 com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = 1069 new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { 1070 public com.google.protobuf.ExtensionRegistry assignDescriptors( 1071 com.google.protobuf.Descriptors.FileDescriptor root) { 1072 descriptor = root; 1073 internal_static_PBPlayer_descriptor = 1074 getDescriptor().getMessageTypes().get(0); 1075 internal_static_PBPlayer_fieldAccessorTable = new 1076 com.google.protobuf.GeneratedMessage.FieldAccessorTable( 1077 internal_static_PBPlayer_descriptor, 1078 new java.lang.String[] { "PlayerId", "Age", "Name", "Skills", }, 1079 com.proto.PlayerModule.PBPlayer.class, 1080 com.proto.PlayerModule.PBPlayer.Builder.class); 1081 internal_static_PBResource_descriptor = 1082 getDescriptor().getMessageTypes().get(1); 1083 internal_static_PBResource_fieldAccessorTable = new 1084 com.google.protobuf.GeneratedMessage.FieldAccessorTable( 1085 internal_static_PBResource_descriptor, 1086 new java.lang.String[] { "Gold", "Energy", }, 1087 com.proto.PlayerModule.PBResource.class, 1088 com.proto.PlayerModule.PBResource.Builder.class); 1089 return null; 1090 } 1091 }; 1092 com.google.protobuf.Descriptors.FileDescriptor 1093 .internalBuildGeneratedFileFrom(descriptorData, 1094 new com.google.protobuf.Descriptors.FileDescriptor[] { 1095 }, assigner); 1096 } 1097 1098 // @@protoc_insertion_point(outer_class_scope) 1099 }
PB序列化
1 //获取一个PBPlayer的构造器 2 Builder builder = PlayerModule.PBPlayer.newBuilder(); 3 //设置数据 4 builder.setPlayerId(101).setAge(20).setName("neil").addSkills(1001); 5 //构造出对象 6 PBPlayer player = builder.build(); 7 //序列化成字节数组 8 byte[] byteArray = player.toByteArray(); 9 System.out.println(Arrays.toString(byteArray)); 10 return byteArray;
运行结果, 一串非常短的byte数组, 远远比json, xml, java序列化要短.
[8, 101, 16, 20, 26, 4, 110, 101, 105, 108, 32, -23, 7]
PB反序列化
1 public static void toPlayer(byte[] bs) throws Exception{ 2 PBPlayer player = PlayerModule.PBPlayer.parseFrom(bs); 3 System.out.println("playerId:" + player.getPlayerId()); 4 System.out.println("age:" + player.getAge()); 5 System.out.println("name:" + player.getName()); 6 System.out.println("skills:" + (Arrays.toString(player.getSkillsList().toArray()))); 7 }
运行结果
playerId:101
age:20
name:neil
skills:[1001]
Java序列化
定义player pojo.
1 private long playerId; 2 private int age; 3 private String name; 4 private List<Integer> skills = new ArrayList<>();
1 Player player = new Player(101, 20, "neil"); 2 player.getSkills().add(1001); 3 4 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 5 ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); 6 7 //写入对象 8 objectOutputStream.writeObject(player); 9 10 //获取 字节数组 11 byte[] byteArray = byteArrayOutputStream.toByteArray(); 12 System.out.println(Arrays.toString(byteArray)); 13 return byteArray;
运行结果, 非常长的一个byte数组
[-84, -19, 0, 5, 115, 114, 0, 15, 99, 111, 109, 46, 106, 97, 118, 97, 46, 80, 108, 97, 121, 101, 114, -73, 43, 28, 39, -119, -86, -125, -3, 2, 0, 4, 73, 0, 3, 97, 103, 101, 74, 0, 8, 112, 108, 97, 121, 101, 114, 73, 100, 76, 0, 4, 110, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 76, 0, 6, 115, 107, 105, 108, 108, 115, 116, 0, 16, 76, 106, 97, 118, 97, 47, 117, 116, 105, 108, 47, 76, 105, 115, 116, 59, 120, 112, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 101, 116, 0, 4, 110, 101, 105, 108, 115, 114, 0, 19, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 65, 114, 114, 97, 121, 76, 105, 115, 116, 120, -127, -46, 29, -103, -57, 97, -99, 3, 0, 1, 73, 0, 4, 115, 105, 122, 101, 120, 112, 0, 0, 0, 1, 119, 4, 0, 0, 0, 1, 115, 114, 0, 17, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 18, -30, -96, -92, -9, -127, -121, 56, 2, 0, 1, 73, 0, 5, 118, 97, 108, 117, 101, 120, 114, 0, 16, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 78, 117, 109, 98, 101, 114, -122, -84, -107, 29, 11, -108, -32, -117, 2, 0, 0, 120, 112, 0, 0, 3, -23, 120]
Java反序列化
1 ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(bs)); 2 Player player = (Player)inputStream.readObject(); 3 4 //打印 5 System.out.println("playerId:" + player.getPlayerId()); 6 System.out.println("age:" + player.getAge()); 7 System.out.println("name:" + player.getName()); 8 System.out.println("skills:" + (Arrays.toString(player.getSkills().toArray())));
运行结果
playerId:101
age:20
name:neil
skills:[1001]
对比
经过上面运行结果的对比可以看出来, PB是一个非常高效的序列化协议.
相对于Java这种数据类型固定长度的序列化(int 4字节, long 8字节), PB提供了可伸缩性的数据类型(int 1-5字节).
当数据比较小的时候int只占用1个字节, 而大部分场景下, 数据都是很小的, 不然jdk本身也不会缓存 -127~128了.