在调试视图中:
这是编码成凌乱字符串的代码......
((S2CEnterCollection)objS2c).toByteString().toStringUtf8();
输出:
���"default(
���"default(
���"default(
���"default(
���"default(
����"default(
����"default(
�����"default(
以下是具有正确字符串的代码:
((S2CEnterCollection)objS2c).toString()
原始字符串是:
cardList {
cardId: 100001
liked: 100
number: 10
finder: "default"
rank: 1
}
cardList {
cardId: 100002
liked: 123
number: 10
finder: "default"
rank: 1
}
cardList {
cardId: 100003
liked: 543
number: 10
finder: "default"
rank: 1
}
cardList {
cardId: 100004
liked: 766
number: 10
finder: "default"
rank: 1
}
cardList {
cardId: 100005
liked: 78
number: 10
finder: "default"
rank: 1
}
cardList {
cardId: 100006
liked: 89
number: 123
finder: "default"
rank: 1
}
cardList {
cardId: 100007
liked: 199
number: 567
finder: "default"
rank: 1
}
cardList {
cardId: 100008
liked: 90909
number: 232
finder: "default"
rank: 1
}
那么,有没有人知道它是如何运作的?
答案 0 :(得分:3)
protobuf数据是二进制的,不是编码文本。你不能通过像UTF-8这样的编码来运行它,并期望获得一个字符串(或者期望它仍然有效)。将protobuf数据转换为字符串的唯一方法是通过base-N编码运行一些N,通常为64(因为它在大多数平台上都得到很好的支持)。
答案 1 :(得分:2)
这个凌乱的字符串可能绝对正确。问题是:你假设它是一个人类可读的字符串,而事实并非如此。 toByteString(),我引用:
Serializes the message to a ByteString and returns it. This is just a trivial wrapper around writeTo(CodedOutputStream).
https://developers.google.com/protocol-buffers/docs/reference/java/index - 寻找MessageLite。
这可能是您可能用于通过网络传输的格式,或者您可能存储在具有数百万条记录的文件中的格式。它并不意味着人类可读 - 它意味着相对较小的机器可读表示。因此它使用标签标识符(小数字)而不是字段名称,可变长度编码和各种其他技巧来实现最小化大小而牺牲可读性。
https://developers.google.com/protocol-buffers/docs/encoding
答案 2 :(得分:1)
我更喜欢使用Google自己的com.google.protobuf.TextFormat类,该类使用“print”方法构造Protobuf对象内容的可读表示形式。在下面的示例中,PayloadContent可以是任何消息:
PayloadContent pc = PayloadContent.newBuilder().setContent........build();
String text = TextFormat.shortDebugString(pc);
如果你想要看到“Byte”格式,那么肯定会将ByteString表示转换为Base64 - 但这对于人类阅读并没有太大用处:)