我使用redis存储位域数据,并在每个偏移量上设置u4值。
我需要在Nodejs服务器中获取缓冲区
对于 0-7 ,redis返回正确的缓冲区
但是当设置 8-15 值时。它会返回一个奇怪的缓冲区.Uint8Array视图进入缓冲区并显示 [239,191,189] ,表示凌乱的代码。
这是复制到运行的测试代码
btw问题ocurrs with resoponse buffer.Trying得到#0值是好的。
const http = require('http');
const url = require('url');
const fs = require('fs');
const redis = require('redis'),
RDS_PORT = 6379,
RDS_HOST = '139.199.33.69',//139.199.33.69
RDS_OPTS = {detect_buffers: true},
client = redis.createClient(RDS_PORT, RDS_HOST, RDS_OPTS);
console.log('redis ready')
const canvas_name = 'canvas-bitfield';
client.del(canvas_name)
client.send_command("bitfield",[canvas_name,'SET','u4','#0',10,'OVERFLOW','FAIL'])
client.send_command('bitfield',[canvas_name,'GET','u4',0],redis.print) //reply:10
client.get(canvas_name,function(err, reply){
if(err){console.log(err)}
const buff = Buffer.from(reply.toString());
const view8 = new Uint8Array(buff);
console.log(view8) //Uint8Array(3) [239, 191, 189]
})
答案 0 :(得分:2)
为什么redis返回[239,191,189]响应缓冲区?
请注意,reply
是String
而不是Buffer
! 为什么?您正在使用detect_buffers: true
。从redis
包的文档中,将此选项设置为true,reply
的类型取决于传递给client.get()
的第一个参数的类型。由于你传递了一个 String (canvas_name
是一个String),所以reply的值也是 String :
client.get(canvas_name,function(err, reply){
console.log(typeof reply) // => String
// ...
为了实现这一点,redis
包internally进行函数调用:Buffer.toString()
将您的<Buffer a0>
缓冲区转换为字符串,然后传递给它字符串回调;绑定到reply
。问题是Buffer.toString()
没有传递任何参数,将尝试使用UTF-8解码缓冲区,但<Buffer a0>
不是有效的UTF-8字符串!在这种情况下,{。{3}}的Node.js返回U + FFFD REPLACEMENT CHARACTER。因此reply
是一个只包含一个U + FFFD或65533字符的字符串。
client.get(canvas_name,function(err, reply){
console.log(reply.length); // 1
console.log(reply.charCodeAt(0)) // => 65533
// ...
此数字(65533)来自 redis(Node.js)无法将您的缓冲区解析为UTF-8字符串!从那里,您将65533放入缓冲区并创建一个[239, 191, 189]
的Uint8Array:
console.log(Buffer.from("\uFFFD")) // => <Buffer ef bf bd>
console.log(new Uint8Array(Buffer.from("\uFFFD"))); // => Uint8Array(3) [239, 191, 189]
要快速解决问题,您需要告诉redis
包不要转换
缓冲区到String。而是直接获取缓冲区:
client.get(new Buffer(canvas_name), function(err, reply) {
console.log(typeof reply) // => Buffer
console.log(reply) // => <Buffer a0>
if(err){console.log(err)}
const view8 = new Uint8Array(reply);
console.log(view8) // => Uint8Array(3) [160]
});
注意:具有0-7范围内十进制值的缓冲区将成功解码为UTF-8字符串,这就是您巧合地获得正确缓冲区的原因。