在Redis协议规范中,提到:
“状态回复不是二进制安全的,不能包含换行符。”字符串/文件是二进制安全的意味着什么?为什么 Redis 中的状态回复不能是二进制安全的?
截至24年11月26日更正
术语“二进制字符串”或“二进制数据”是一个常见的用词不当。 二进制是一种数字基数,与您正在处理的数据没有直接关系。
我将参考Redis在YouTube上发布的这段视频来解释:
https://www.youtube.com/watch?v=7CUt4yWeRQE
视频解释了Redis中的二进制字符串是可以包含任何类型数据的字符串,对字符串中每个元素的值没有限制。他们给出的例子是你可以将图像数据直接放入字符串中。
在“非二进制安全”字符串中,或者仅限于 ASCII 字符或 UTF-8 序列的字符串中,另一种方法是使用基数重新编码图像数据(或“二进制数据”)。 64,它允许仅用 ASCII 字符表示。
因此,根据 Redius,“二进制安全字符串”的定义将是一个字节值序列,其中每个字节都有一个域
[0, 255]
。 Redis 知道序列中的元素数量,因为元素数量是在字符串数据的其余部分之前发送的。
我不认为这是一个通用的定义,当有人谈论“二进制数据”时,一定要验证他们想说什么,因为它经常被误解。
例如,在 Python 中,它们被称为
bytes
对象,并以 b
前缀编写:
example = b'SET foo \x00'
在 C 语言中将是:
char example[] = "SET foo \x00";
不幸的是,这无助于精确定义什么是“非二进制安全字符串”。
根据我对其协议的理解以及它们主要用于响应的事实,您可能可以假设它是纯 ASCII 字符,不包括回车符或换行符。
之前的回答
二进制安全字符串解析器会考虑字符串中单个字符中的所有可能值
0 - 255
,该字符串可能不是以 null 结尾的(否则它的长度是已知的)。如果字符串解析器不是二进制安全的,则它需要一个以 null 结尾的字符串(字符串末尾的二进制 0
)。
通常,字符串解析器不是二进制安全的。许多解析期望正常的可打印字符和字符串末尾的
0
。如果此类字符串末尾没有 0
,则很容易出现分段错误。
二进制安全解析器可能正在解析任意数据(可能是文本或其他数据)。
编辑:
“字符串/文件二进制安全意味着什么?”
“为什么 Redis 中的状态回复不能是二进制安全的?”
\r\n
的第一个实例处结束。这就是解析器计算字符串长度的方式。因此,如果它在回复结束之前找到
\r\n
,它将停止解析并忽略之后的所有内容。