博客搬家,原地址:https://langzi989.github.io/2017/06/07/protoBuffer中string与byte类型区别/

从上一节protobuffer的介绍中我们知道字符串类型在protobuffer中有string和bytes两种类型,那这两种类型有什么区别呢,什么时候用string,什么时候用bytes。在C++中两种类型分别对应的是什么类型.下面将揭开迷雾

string与bytes区别

按照经验我们知道bytes一般适用于存储二进制数据的,但在C++中,string既可以存储ASCII文本字符串,也能存储任意多个\0的二进制序列,那两者的区别在哪里呢?

  • string类型(protobuffer中的string,与C++区别开)不能存储非法的UTF-8字符,如果遇到该字符,序列化的时候将会出错。

[libprotobuf ERROR google/protobuf/wire_format.cc:1091] String field ‘str’ contains invalid UTF-8 data when serializing a protocol buffer. Use the ‘bytes’ type if you intend to send raw bytes.

###出现上述错误的原因
这里从ProtoBuf的源码进行分析。protoBuf在序列化的过程中,都会调用SerializeFieldWithCachedSizes这个函数。我们看一下序列化string和bytes在序列化过程中的区别。

对于string类型:

case FieldDescriptor::TYPE_STRING: {string scratch;const string& value = field->is_repeated() ?message_reflection->GetRepeatedStringReference(message, field, j, &scratch) :message_reflection->GetStringReference(message, field, &scratch);VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,field->name().c_str());WireFormatLite::WriteString(field->number(), value, output);break;
}

对于bytes类型:

case FieldDescriptor::TYPE_BYTES: {string scratch;const string& value = field->is_repeated() ?message_reflection->GetRepeatedStringReference(message, field, j, &scratch) :message_reflection->GetStringReference(message, field, &scratch);WireFormatLite::WriteBytes(field->number(), value, output);break;
}

从上面可以看到,序列化string和bytes的区别主要在于:string类型序列化调用了VerifyUTF8StringNamedField函数检验string中是否有非法的UTF-8字符。其中VerifyUTF8StringNamedField实现如下:

void WireFormat::VerifyUTF8StringFallback(const char* data,int size,Operation op,const char* field_name) {if (!IsStructurallyValidUTF8(data, size)) {const char* operation_str = NULL;switch (op) {case PARSE:operation_str = "parsing";break;case SERIALIZE:operation_str = "serializing";break;// no default case: have the compiler warn if a case is not covered.}string quoted_field_name = "";if (field_name != NULL) {quoted_field_name = StringPrintf(" '%s'", field_name);}// no space below to avoid double space when the field name is missing.GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "<< "UTF-8 data when " << operation_str << " a protocol "<< "buffer. Use the 'bytes' type if you intend to send raw "<< "bytes. ";}
}

string和bytes类型在C++和Java中的区别

protobuf类型在C++和java中的类型对应如下:

  • 在C++中,string和bytes的实现都是std::string类型。
  • 在Java中string和bytes类型的实现分别是String和ByteString。

为什么bytes类型可以描述string类型,还需要string呢?

根据论坛上说的,string类型在Java中有较多的API可供使用,而bytes较少,所以能定义为string的尽量定义为string,如果字段值确定或者可能含有非法的utf-8编码,则使用bytes类型。

protobuffer中string和bytes类型相关推荐

  1. Java中 String 转 Long 类型需要注意的事项

    Java中 String 转 Long 类型需要注意的事项 注意事项: 1.字符串内不能包含除数字之外的字符 不然会报错,java.lang.NumberFormatException 2.字符串长度 ...

  2. 面试必考之Java中String是基础类型?是包装类型?

    我们都知道,Java中String不属于基础数据类型.基础类型只有8中基本数据类型:byte.short.int.long.float.double.char.boolean,而String是最常用到 ...

  3. Java中String转int类型出现的问题及解决方式

    一般在Java中String转为Int主要有两种方法: 1. Integer.parseInt(str); 2. Integer.valueOf(str); ps:两者的不同之处: Integer.p ...

  4. golang 中string和int类型相互转换

    总结了golang中字符串和各种int类型之间的相互转换方式: string转成int: test_int, err := strconv.Atoi(test_string) if err != ni ...

  5. golang string转int8_golang 中string和int类型相互转换

    Notepad++ 默认快捷键 Notepad++绝对是windows下进行程序编辑的神器之一,要更快速的使用以媲美VIM,必须灵活掌握它的快捷键,下面对notepad++默认的快捷键做个整理(其中有 ...

  6. java中String转Long类型

    public class StringToLong {public static void main(String[] args) {String str="123";Long l ...

  7. JAVA中String与Date类型互转

    String2Date              &&      Date2String 首先,感谢阅览,能够帮到你是我的荣幸,有不足的挺多指教. 在java中不支持String和Da ...

  8. Go 中string和int类型相互转换

    string转成int: int, err := strconv.Atoi(string) string转成int64: int64, err := strconv.ParseInt(string, ...

  9. python中byte类型_详解python string类型 bytes类型 bytearray类型

    搜索热词 一.python3对文本和二进制数据做了区分.文本是Unicode编码,str类型,用于显示.二进制类型是bytes类型,用于存储和传输.bytes是byte的序列,而str是unicode ...

  10. python str byte编码_Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题...

    Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str ...

最新文章

  1. CNN可视化最新研究方法进展(附结构、算法)
  2. 《庆余年》是爆了,但想打高分的阅文仍然没有公式可套
  3. Elasticsearch实战篇——Spring Boot整合ElasticSearch
  4. Spring学习之路-从入门到放弃
  5. 蓝桥杯 ADV-112 算法提高 c++_ch02_01
  6. Ruby语法解释:attr_reader,attr_writer和attr_accessor
  7. 【C语言入门】ZZULIOJ 1000-1005
  8. 实战项目-python库分析科比生涯数据
  9. 华为机考 叠积木 python (以及处理输入)
  10. 家用双千兆路由器推荐_千兆以上(专业级)无线路由器路由器哪款好
  11. uniapp获取云服务空间 数据
  12. java判断200以内的素数_java判断101-200之间的素数并输出
  13. 学微积,用手机,人人“知识共享”学真知
  14. 微信CRM系统对客户关系管理有什么好处?
  15. 客户开发篇 | 外贸业务员怎么打电话开发跟进客户呢?
  16. 网络技术交流QQ群:46855032
  17. 录用率48%到68%! I3D/ICDAR/CogSci/ICIP2023即将截稿
  18. jQuery学习教程二十: jQuery 遍历 - 后代
  19. 微型计算机的难点,微机原理及应用重点难点.PDF
  20. 全新Thinkphp养我吧宠物区块链网站源码+可封装APP源码 免费下载 源码搭建教程

热门文章

  1. openSUSE 跨版本升级
  2. FragmentStatePagerAdapter写法
  3. jsp+servlet实现最基本的注册登陆功能
  4. netbeans-xdebug
  5. js基础知识(pomelo阅读)
  6. 基础算法1——插入排序和希尔排序
  7. [转]ios面试题收集(二)
  8. 【ZooKeeper Notes 6】客户端对zookeeper的操作是不可回退的 [OK]
  9. JQuery Lightbox -- 一个简单而又谦恭的用来把图片覆盖在当前页面上的脚本
  10. 1.SOA架构:服务和微服务分析及设计--- 理解面向服务