Protocol buffers 序列化消息中的新行字符
某些protobuf消息序列化为字符串时,其内部有新行字符Protocol buffers 序列化消息中的新行字符,protocol-buffers,Protocol Buffers,某些protobuf消息序列化为字符串时,其内部有新行字符\n。通常,当消息的第一个字段是字符串时,新行字符在消息之前加上前缀。但是WA也发现了中间有新行字符的消息。 换行符的问题是,您希望将消息逐行保存到一个文件中。新行字符打断了行并使消息无效 示例.proto syntax = "proto3"; package data_sources; message StringFirst { string key = 1; bool valid = 2; } message Strin
\n
。通常,当消息的第一个字段是字符串时,新行字符在消息之前加上前缀。但是WA也发现了中间有新行字符的消息。
换行符的问题是,您希望将消息逐行保存到一个文件中。新行字符打断了行并使消息无效
示例.proto
syntax = "proto3";
package data_sources;
message StringFirst {
string key = 1;
bool valid = 2;
}
message StringSecond {
bool valid = 1;
string key = 2;
}
示例.py
from protocol_buffers.data_sources.example_pb2 import StringFirst, StringSecond
print(StringFirst(key='some key').SerializeToString())
print(StringSecond(key='some key').SerializeToString())
输出
b'\n\x08some key'
b'\x12\x08some key'
这是预期/期望的行为吗?如何防止新行字符?protobuf是一个二进制协议(除非您讨论的是可选的json)。因此:无论何时,只要您以任何方式将其视为文本,您都是在错误地使用它,行为将是未定义的。这包括担心是否存在CR/LF字符,但也包括nul字符(0x00),在许多框架(特别是C字符串)中,在基于文本的API中,nul字符通常被解释为字符串结尾 具体而言:
- LF(0x0A)与“字段1,长度前缀”的字段标题相同
- CR(0x0D)与“字段1,固定32位”的字段标题相同
- 0x00、0x0A或0x0D中的任何一个都可以作为长度前缀出现(表示长度为0、10或13)
- 0x00、0x0A或0x0D中的任何一个都可以在二进制数据中自然出现(
)字节
- 0x00、0x0A或0x0D中的任何一个都可以在任何数字类型中自然出现
- 0x0A或0x0D可以在文本数据中自然出现(如果您的原始框架允许字符串中任意使用nul字符,那么0x00也可以出现,所以…不是C字符串)
- 可能还有一系列其他的事情
将二进制数据作为文本处理的最常见方法是使用base-N编码;base-16(十六进制)便于显示和读取,但base-64在传输相同字节数所需的字符数方面更为有效。因此,如果可能的话:根据需要转换为base-64或从base-64转换为base-64。Base-64从不包含任何不可打印的字符,因此您将永远不会遇到CR/LF/nul。谢谢。为了回答的完整性,以下是如何将其转换为base-16和base-16:
text=bytes.hex(message.SerializeToString())
和message.ParseFromString(bytes.fromhex(text))