java解析.proto文件具体方法 (一)

2014-11-24 11:54:46 · 作者: · 浏览: 51

 一、前言
  本文将介绍用java解析.proto文件。
  由于protobuffer的java库里面有提供可以直接解析.ptoto文件的相关类,所以并不能像C++那样直接可以解析.proto文件,我google了半天才在网上找到方法,于是便有了这篇博文。(此处需要用到protobuf的jar文件,可以点击此处下载
  二、具体解析方法
  不能直接用protobuf提供的库来解析.proto文件,但是可以用它提供的解析的.desc文件来获取.proto文件信息。所以要先调用如下命令生成desc文件:
[plain]
protoc -I=$SRC_DIR descriptor_set_out=$DST_DIR/***.desc $SRC_DIR/***.proto

protoc -I=$SRC_DIR descriptor_set_out=$DST_DIR/***.desc $SRC_DIR/***.proto

  然后就可以用FileDescriptorSet这个来解析了,然后获得FileDescriptor,在看官方网上关于protobuf的API就可以得到想要的信息了。具体看如下代码:
[java]
package com.test.proto;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.DescriptorProtos.FileDescriptorSet;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;

public class Test {

public static void main(String[] args) throws Exception {

Runtime run = Runtime.getRuntime();

String dir = System.getProperty("user.dir");
String source = dir + "/protoc/";
String cmd = "cmd /c " + source + "protoc.exe -I=" + source + " --descriptor_set_out="+ source +"addressbook.desc "+ source +"addressbook.proto";
System.out.println(cmd);

Process p = run.exec(cmd);

// 如果不正常终止, 则生成desc文件失败
if (p.waitFor() != 0) {
if (p.exitValue() == 1) {//p.exitValue()==0表示正常结束,1:非正常结束
System.err.println("命令执行失败!");
System.exit(1);
}
}

Map mapping = new HashMap();

FileInputStream fin = new FileInputStream("addressbook.desc");
FileDescriptorSet descriptorSet = FileDescriptorSet.parseFrom(fin);

for (FileDescriptorProto fdp: descriptorSet.getFileList()) {
FileDescriptor fd = FileDescriptor.buildFrom(fdp, new FileDescriptor[]{});

for (Descriptor descriptor : fd.getMessageTypes()) {
String className = fdp.getOptions().getJavaPackage() + "."
+ fdp.getOptions().getJavaOuterClassname() + "$"
+ descriptor.getName();
List types = descriptor.getFields();
for(FieldDescriptor type : types) {
System.out.println(type.getFullName());
}
System.out.println(descriptor.getFullName() + " -> " + className);
}
}



// Descriptor md = fd.getDescriptorForType();
// byte[] data = null ;
// DynamicMessage m = DynamicMessage.parseFrom(md, data);



}

}

package com.test.proto;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.DescriptorProtos.FileDescriptorSet;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;

publi