C# 是否可以使用google.protobuffer来序列化数据,而不在每个数据字段的长度前加前缀?

C# 是否可以使用google.protobuffer来序列化数据,而不在每个数据字段的长度前加前缀?,c#,protocol-buffers,protobuf-net,C#,Protocol Buffers,Protobuf Net,默认情况下,除非我做错了什么,protobuf会在所有数据字段前面加上后面的数据长度。例如,如果我这样做: class Program { static void Main(string[] args) { MessagePayload msg = new MessagePayload() { Message = "hello" }; var bytes = new byte[8];

默认情况下,除非我做错了什么,protobuf会在所有数据字段前面加上后面的数据长度。例如,如果我这样做:

class Program
{
    static void Main(string[] args)
    {
        MessagePayload msg = new MessagePayload()
        {
            Message = "hello"
        };

        var bytes = new byte[8];

        var output = new CodedOutputStream(bytes);

        output.WriteMessage(msg);

        Console.WriteLine(CryptoBytes.ToHexStringLower(bytes));

        Console.ReadLine();
    }
}
它打印出:

07120568656c6c6f
但我想要的是:

0568656c6c6f

有没有一种方法可以让protobuf以某种方式执行此操作,而无需手动删除长度字段

否。如此处编码中所述,字符串必须以其大小作为前缀。“导线类型为2(长度分隔)意味着该值是一个可变编码长度,后跟指定的数据字节数。”

唯一可移动的字节是
07
——它不是常规protobuf规范的一部分,该消息的原始protobuf输出只是
120568656C6F
。前导的
07
是一个不相关的长度前缀,它可能是
codedOutStream
的一部分,但不是常规protobuf输出的一部分。通过不使用
codedOutStream
,而只是使用
msg
上的其他可用方法,您可能可以避免这种情况

这里的
12
表示“字段编号:2,类型:长度分隔”。这告诉我,
Message
很可能不是
MessagePayload
上定义的唯一字段,所以不:您不能删除它。即使它是
MessagePayload
上唯一的字段,protobuf规范也不在乎:每个字段都有一个字段头

老实说,如果您只想发送一个字符串,那么:不要使用protobuf-只需使用UTF-8对字符串进行编码,以您选择的任何方式预先添加长度前缀(protobuf使用“varint”),就完成了。但是,如果您想要发送更复杂的结构化数据,则需要一些开销来实现这一点。这就是这里的
12


记录如下:protobuf中定义了6种“导线类型”,其中只有一种(导线类型2)包含长度前缀。许多字段不涉及长度前缀。在您的示例中,实际protobuf数据中唯一的长度前缀是
05
,这是您希望保留的字节之一。

为什么要使用典型的二进制协议进行打印?重新标记:这不是protobuf-net-看起来像Google C版本(protobuf-net是同一规范的完全独立实现)谢谢你的提示。但我需要开始时的初始长度。它不仅仅是展示了什么,还有很多。我需要序列化一个相对较大的数据结构(~150-~600字节)。我使用protobuf是因为它将用于文档编制,这样其他人就可以简单地复制.proto文件并实现相同的文件,而不必自己实现数据结构,这可能会非常棘手。@kodty你说你需要初始长度,但在这个问题上你删除了初始长度。你可以理解为什么我会被这搞糊涂。。。但是:如果删除字段标题,则任何protobuf库都无法使用data05 68656C6F->07,因为删除了1205而减少为05。它只用于序列化,不用于反序列化。序列化的数据被发送到一个不是protobuf的端点,因此,如果删除了头,这并不重要——实际上是必要的。对其他开发人员说“构建这个.proto文件,填充数据,然后删除标题”比说“你必须手动序列化这个结构中的数据”要简单得多,因为结构可能很复杂。@Kotty k,但没有protobuf库可以帮你这么做,我刚刚写了一些东西来手动删除字段长度标题,它工作得很好。