我上次写过google protocol buffer的utf-8的问题 ,根据protocol作者Kenton Varda 的描述 :

    C++ Protocol Buffers use UTF-8 for all text encoding, regardless of platform.  If you want to use some other encoding in your code, you will have to manually convert between that and UTF-8 when interacting with Protocol Buffers.
    In Java and Python everything is taken care of automatically, since these languages have built-in unicode support.  In Java, protocol buffers uses String object (which are unicode) to represent strings, and in Python you can use the "unicode" builtin type for unicode.

    翻译一下 :在c++中用utf-8来作为文本的编码,平台无关的。如果你想用其他的编码,你需要手工转换到utf-8才行。在java和python中,需要小心编码自动转换,因为这两个语言是内建unicode的支持。在java中protocol buffer用String对象(unicode的)来展现字符串,在python中,你可以用内置的unicode来展现ucnode字符串。

   解释一下 :protocol buffer的proto文件你要是用string类型,那么你在c++中用的是utf-8,在java和python中必须用unicode。如果不是,你可以手工去转换。比如,在python中:

    data是utf-8的,但是protocol python版本要求是unicode的,怎么办?

    cont = MsgContent()

    cont.strcont = data.decode('utf-8')#必须从utf-8解码为unicode

    buff = cont.SerializeToString()#序列化之后的字符串,就不要管了

 

    同样的道理,parse完毕后,string的字段都是unicode的

    cont = MsgContent()

    cont.ParseFromString(buff)

    data = cont.strcont#这是unicode的

    data = data.encode('utf-8')#需要什么编码,就要从unicode转换成什么编码

 

    最最重要的一点,如果这样你嫌麻烦,我估计很多人都嫌麻烦,比如数据库、文件中、甚至传输过程中的编码都是utf-8,每次都需要转成unicode再序列化,然后转换回来之后还得转成utf-8,你可以用bytes,bytes是不做任何处理的。

    最后补充 :我认为Kenton Varda 在这个问题上 ,是多虑了,实际上java和python的字符串,任何的编码都是支持的,而不只是unicode,比如在python中,如果文件中标明了#-*- coding:utf-8 -*-,则代码中所有手工输入的字符串都是utf-8的,如果读取文件、从数据库中读取数据、包括从网络上接受的数据,都是utf-8,整个都统一,这样才是最为方便的,而自动转换实在是多此一举。

 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐