protobuf bytes类型

所有的序列化操作都会在SerializeFieldWithCachedSizes这个函数里进行。根据不同的类型调用对应的序列化函数,例如对于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类型调用了VerifyUTF8StringNamedField函数

序列化函数不同:WriteString vs WriteBytes

出于效率,我们应当在确定字段编码格式后直接使用bytes,减少utf8编码的判断,效率上会有提高。 注意以上代码在pb2.6下,2.4不会输出field_name。

据了解java接口上有一定的区别,分别对应String以及ByteString。

  •