最近由于项目需要,大致研究了一下protobuf的java使用。说实话,习惯了C++的protobuf,java用起来真别扭。
由于需要将protobuf序列化后,存入redis,而且redis没法直接存储非字符串的数据,所以我只能想办法将protobuf序列化成字符串。
protobuf的java实现里,并没有直接序列化成String类型变量的方法,但是提供了toByteArray()方法,可以序列化成byte[]。
于是乎很容易想到可以这么做:
byte[] raw_bytes = proto.toByteArray(); String raw_string = new String(raw_bytes);
这样就把protobuf序列化成String类型了,但是,将raw_string反序列化回protobuf时,就发生了错误,无法生存原protobuf的数据,这是为什么呢?
原因其实是在意java中String类型的编码。
默认情况下,String类型是编码成utf8类型的,utf8类型是可变编码的,在用byte[]初始化String时,很有可能会使String中的数据与原始的byte[]不一样。
知道原因后,怎么做才能避免这种情况的发生呢?
可以这么做:
byte[] raw_bytes = proto.toByteArray(); String raw_string = new String(raw_bytes, "ISO-8859-1");
没错,就是改变String初始化时,其编码的方式。IOS-8895-1包括了书写所有西方欧洲语言不可缺少的附加字符,其中 0~127的字符与ASCII码相同,它是单字节的编码方式,这样以它为编码生成的String里的byte[]就跟原来的byte[]是一样的。
protobuf在java中的字符串化,布布扣,bubuko.com
时间: 2024-10-21 05:16:28