二进制安全
C字符串必须符合某种编码(如ASCII),且出末尾外不能包含空字符(’\0’)。
由于这些限制,C字符串只能保存文本数据,不能保存二进制数据(二进制数据中不能包含’\0’对应的二进制数据,那么保存时就有可能会出错)。所以这不是二进制安全的。
示例:str=“0123456789\00123456789”
C字符串会认为str的长度为10,因为\0在C字符串中具有特殊意义,在识别到‘\0’后就会结束。而在Redis中,str的长度为21。
因为SDS中的API都是二进制安全的,所有SDS API都会以处理二进制的方式来处理SDS存放在buf数组里的数据(换句话说,buf数组里存放的依然是文本数据,但是所有的SDSAPI都会以二进制处理方式来处理buf数组),程序不会对数据做任何操作,故SDS中的buf属性也被称为“字节数组”。
SDS API通过len属性便可以得知buf数组中的字符串长度,而不是通过buf中的’\0’来获取字符串长度。
因此,Redis不仅可以保存文本数据,还可以保存任意格式的二进制数据(即buf数组中本身保存的还是文本数据,但是所有的SDS API都是以二进制的方式来处理buf中的文本数据,这样就实现了保存二进制数据)。
兼容部分C字符串函数
首先来看SDS-buf数组中保存的字符串示例
buf数组中总会追加一个’\0’,并且不会计入字符串长度。多分配一个字节来容纳这个空字符,就是未来使那些保存文本数据的SDS可以重用一部分<string.hj>库定义的函数。
比如上图中的SDS就可以调用<string.h>/strcasecmp函数,这样就不用在重写一个与此功能相同的函数了。
这样可以有效避免不必要的代码重复。