【protocol buffers】java解析.proto文件具体方法

  一、前言

  本文将介绍用java解析.proto文件。
  由于protobuffer的java库里面有提供可以直接解析.ptoto文件的相关类,所以并不能像C++那样直接可以解析.proto文件,我google了半天才在网上找到方法,于是便有了这篇博文。(此处需要用到protobuf的jar文件,可以点击此处下载)

  二、具体解析方法

  不能直接用protobuf提供的库来解析.proto文件,但是可以用它提供的解析的.desc文件来获取.proto文件信息。所以要先调用如下命令生成desc文件:
protoc -I=$SRC_DIR descriptor_set_out=$DST_DIR/***.desc $SRC_DIR/***.proto

  然后就可以用FileDescriptorSet这个来解析了,然后获得FileDescriptor,在看官方网上关于protobuf的API就可以得到想要的信息了。具体看如下代码:
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<String, String> mapping = new HashMap<String, String>();
		
		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<FieldDescriptor> 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);
		

		
	}

}

  三、结果截图

【protocol buffers】java解析.proto文件具体方法_第1张图片

  四、附件(addressbook.proto)

package com.example.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 phone = 4;
}

message AddressBook {
  repeated Person person = 1;
}

(全文完)
注:这个是本人原创的,如需转载,请尊重劳动果实,务必保持 原链接( http://blog.csdn.net/lufeng20/article/details/8736584)

你可能感兴趣的:(语言,protobuf)