某些protobuf消息在序列化为字符串时,其内部具有换行符$points = \App\Prize::selectRaw('user_id,COUNT(user_id), date(created_at)')
->groupBy("date(prizes.created_at), user_id")
->orderBy("date(created_at)","DESC")
->having("user_id","=",1)
->get();
。通常,当消息的第一个字段是字符串时,则在消息之前添加换行符。但是,wa还在中间某处发现了带有换行符的消息。
换行符的问题是当您要将消息逐行保存到一个文件中时。新的换行符使该行中断并使消息无效。
example.proto
\n
example.py
syntax = "proto3";
package data_sources;
message StringFirst {
string key = 1;
bool valid = 2;
}
message StringSecond {
bool valid = 1;
string key = 2;
}
输出
from protocol_buffers.data_sources.example_pb2 import StringFirst, StringSecond
print(StringFirst(key='some key').SerializeToString())
print(StringSecond(key='some key').SerializeToString())
这是预期/期望的行为吗?如何防止换行符?
答案 0 :(得分:3)
protobuf是一个二进制协议(除非您在谈论可选的json东西)。因此:无论何时以任何方式将其视为类似于文本的 ,您都在错误地使用它,并且行为是不确定的。这包括担心是否存在CR / LF字符,但也包括诸如nul字符(0x00)之类的东西,在许多框架中,该字符通常被解释为基于文本的API中的字符串结尾(特别是C-字符串)。
特别是:
bytes
)中自然会出现0x00、0x0A或0x0D中的任何一个所以:再次-如果包含“特殊”文本字符是有问题的:您使用的是错误的。
将二进制数据作为文本处理的最常见方法是使用base-N编码。 base-16(hex)便于显示和读取,但是base-64在传达相同字节数所需的字符数方面效率更高。因此,如果可能的话:根据需要转换为base-64。 Base-64永远不会包含任何不可打印的字符,因此您永远不会遇到CR / LF / nul。