NodeJS 如何使用节点在redis中存储二进制对象?

jljoyd4f  于 2022-12-12  发布在  Node.js
关注(0)|答案(7)|浏览(211)

我试图在redis中保存一个二进制对象,然后将其作为图像返回。
下面是我用来保存数据的代码:

var buff=new Buffer(data.data,'base64');
client.set(key,new Buffer(data.data,'base64'));

下面是转储数据的代码:

client.get(key,function(err,reply){
        var data = reply;
        response.writeHead(200, {"Content-Type": "image/png"});
        response.end(data,'binary');

});

数据的前几个字节似乎已损坏。幻数不正确。
做了一些实验:
当我执行以下操作时:

var buff=new Buffer(data.data,'base64');
console.log(buff.toString('binary'));

我得到这个:
0000000:289 504e 470d 0a1a 0a00 0000 0d49 4844在您的计算机上运行的程序
当我这样做的时候

var buff=new Buffer(data.data,'base64');
 console.log(buff);

我得到以下结果:
缓冲区89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00
我不确定c2是从哪里来的

mjqavswn

mjqavswn1#

问题是Redis Node客户端默认将响应转换为JavaScript字符串。
我通过在创建客户机时将return_buffers选项设置为true来解决这个问题。

var client = redis.createClient(7000, '127.0.0.1', {'return_buffers': true});

有关详细信息,请参阅here

sdnqo3pr

sdnqo3pr2#

我无法弄清楚如何存储二进制字符串。
以下是我的解决方法:
其中data是base64字符串中的数据

client.set(count,data);

提供数据:

client.get(last,function(err,reply){
   var data = reply;
   response.writeHead(200, {"Content-Type": "image/png"});
   var buff=new Buffer(data,'base64');
   response.end(buff);
});

这并不理想,因为每次都要进行转换,但它似乎起作用了。

eit6fx6z

eit6fx6z3#

return_buffers的问题是,当你不使用纯缓冲区数据时,你必须做一些事情来将其他缓冲区转换为字符串。
如果您不介意额外的计算周期,您也可以尝试:

// convert your buffer to hex string
client.set(key, mybuffer.toString('hex'));
// create a new buffer from hex string
client.get(key, function (err, val) {
   var bin = new Buffer(val, 'hex');
});
oyjwcjzk

oyjwcjzk4#

对我有效的是,如果它是Buffer,就使用data.toString('binary')。还要确保不要将它重新解释为utf-8,但也要解释为binary

h7appiyu

h7appiyu5#

我找到了这篇关于这个主题的文章,它解释了这样做的含义,我强烈推荐在走这条路之前阅读这篇文章(不管编程语言如何)。
http://qnimate.com/storing-binary-data-in-redis/
总之,由于Redis是一个内存中的键值存储库,所以最好不要在Redis中存储可能很大的值,比如图片,因为这样会很快耗尽可用内存,降低Redis示例的性能。最好将文件的位置存储在Redis中,而不是文件本身。

zvokhttg

zvokhttg6#

这篇文章是旧的,但只是一个更新的答案。正如另一个答案所说,所有的Node.js Redis库都以utf8字符串的形式返回数据,因为这是人们通常需要的。Node.js Redis库,如ioRedis,也提供了其他方法来获取数据作为缓冲区。例如redis.getBuffer而不是redis.get

hi3rlvi2

hi3rlvi27#

我遇到了一个类似的问题,在我的例子中,损坏是与我从Redis获取数据到Nodejs的方式有关。在我的例子中,来自Nodejs的值被正确存储,但当它进入节点时,它被转换为ASCII字符串。我可以用下面的行强制它进入缓冲区。

let file = await r.get(redis.commandOptions({ returnBuffers: true }), `zip/${req.params.taskId}`)

相关问题