我们知道Memecached服务器本身不考虑key(关键字)的编码,如何编码是客户端的事,在Memecached服务器看来,key就是一个字节序 列,而不会将它看成字符序列。如果在应用层传过来的key包含中文字符,客户端就需要先将这个key编码成一个字节序列,这个字节序列还不能含有特殊的控 制符。根据这里的讨论,对Memcached来说,key不能包含NULL, space, CR, LF,它可以包含其它控制符(如TAB),但这并不意味你的应用中就可以包含这些字符,这还依赖于客户端的选择。
在 Memecached的一个比较流行的C#客户端是Enyim,很遗憾的是它并不能很好地处理中文key。它将key变成字符序列时调用的是 Encoding.ASCII.getBytes方法,这个方法不能识别中文,对所有的中文它都返回问号(?),例如ASCII.getBytes("你 好")返回"??",这样明显不是我们想要的,对于下面的程序,它会输出"Hello World"。
这 无疑是Enyim的一个失误,要解决这个问题,只能在应用层对Key先进行编码。另外,虽然Memcached服务器允许包含其它不少控制符,但 Enyim不允许key包含任何ASCII码小于或等于0x20的控制字符,对这些字符也应当编码。考虑这些问题,一个解决方法是使用URL的编 码,URL编码会对所有控制字符,中文字符进行编码。如果还考虑到应用层的key也带有参数,使用URL编码似乎是一种十分理想的方式。
在 Memecached的一个比较流行的C#客户端是Enyim,很遗憾的是它并不能很好地处理中文key。它将key变成字符序列时调用的是 Encoding.ASCII.getBytes方法,这个方法不能识别中文,对所有的中文它都返回问号(?),例如ASCII.getBytes("你 好")返回"??",这样明显不是我们想要的,对于下面的程序,它会输出"Hello World"。
class Program
{
static void Main(string[] args)
{
MemcachedClient mc = new MemcachedClient();
mc.Store(StoreMode.Set, "你好", "Hello World", new TimeSpan(0));
Console.WriteLine(mc.Get("??"));
Console.ReadLine();
}
}
这 无疑是Enyim的一个失误,要解决这个问题,只能在应用层对Key先进行编码。另外,虽然Memcached服务器允许包含其它不少控制符,但 Enyim不允许key包含任何ASCII码小于或等于0x20的控制字符,对这些字符也应当编码。考虑这些问题,一个解决方法是使用URL的编 码,URL编码会对所有控制字符,中文字符进行编码。如果还考虑到应用层的key也带有参数,使用URL编码似乎是一种十分理想的方式。
0 评论:
发表评论