http://www.cnblogs.com/royenhome/archive/2010/10/30/1865153.html
c++端
using namespace::google::protobuf::io;
#define MAX_SIZE 4096
//序列化
char tmpArr[MAX_SIZE];
memset(tmpArr,0,sizeof(tmpArr));
ZeroCopyOutputStream *raw_output = new ArrayOutputStream(tmpArr,addressBook.ByteSize()+1);
CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
if( !addressBook.SerializeToCodedStream( coded_output ))
{
cerr<<"Fail to serial addressbook data!\n";
return;
}
send(socketfd,tmpArr,addressBook.ByteSize(),0);
cout<<"serial address successfully!\n";
delete coded_output;
delete raw_output;
//反序列化
numbytes = recv(soxketfd, buf, MAX_SIZE, 0);
demo::People p;
p.Clear();
if( !p.ParseFromArray(buf,numbytes) )
{
cerr<<"Deserial from addressbook.data failed!\n";
return 0;
}
Java 端
//序列化
socket = new Socket("192.168.51.46", 12345);
People people=People.newBuilder().setId(0)
.setName("Hideto").setEmail("Hideto@gmail.com").build();
people.writeTo(socket.getOutputStream());
socket.getOutputStream().flush();
//
People.toByteArray();
//反序列化
//parseFrom是静态方法
//类型确定是People
people=People.parseFrom(socket.getInputStream());
//类型不确定,由类型的名字,重构message
Package demo中的Class Demo的嵌套类People
className="demo.Demo$People";
public Object objectFromByteBuffer(String className, byte[] buffer)
throws Exception {
Class clazz = Class.forName(className);
// Thread.currentThread().getContextClassLoader().loadClass(className);
Method parseFromMethod = clazz.getMethod("parseFrom", byte[].class);
return parseFromMethod.invoke(null, buffer);
}
//类型不确定,由Descriptor 产生 DynamicMessage
protoc --descriptor_set_out=demo.desc demo.proto
Map<String, String> mapping = new HashMap<String, Descriptor >();
建立Map保存名字和Descriptor 的映射
void init() {
try {
try {
FileInputStream fs = new FileInputStream("src/demo");
FileDescriptorSet descriptorSet = FileDescriptorSet
.parseFrom(fs);
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();
mapping.put(descriptor.getFullName(), descriptor );
}
}
} catch (IOException e) {
System.out.println(e.toString());
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
由名字得到相应的descriptor,然后
public Object objectFromByteBuffer(Descriptor descriptor, byte[] buffer)
throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
int n = bais.read();
byte[] message = new byte[n];
// 由className得到相应的descriptor
DynamicMessage m = DynamicMessage.parseFrom(descriptor, message);
return m;
}
/
People people;
string a;
p.set_id(0);
p.set_name("a");
p.set_email("a@a.net");
p.SerializeToString(&a);
p.ParseFromString(a);
p.set_id(123);序列化,反序列化都正常。
p.set_id(0);会丢失email数据。
原因:p.set_id(0);使string中出现了字符0.