【问题标题】:How to store a binary object in redis using node?如何使用节点将二进制对象存储在redis中?
【发布时间】:2014-01-11 00:15:01
【问题描述】:

我正在尝试将二进制对象保存在 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: c289 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 来自哪里

【问题讨论】:

  • 尚未以这种方式处理图像,但不应“解码”base64 中编码的内容?
  • console.log(reply) 会得到什么?您能否详细说明通过将图像放入 Redis 来完成的工作?这不是存储大量二进制数据的最佳方式。
  • 数据以 base64 的形式出现,试图保存二进制文件
  • 跟进这个问题:我正在尝试做基本相同的事情,当我用get读出它时,即使我写的是相同的东西,字符串长度也是不同的。

标签: node.js redis node-redis


【解决方案1】:

问题在于 Node 的 Redis 客户端默认将响应转换为 JavaScript 字符串。

我通过在创建客户端时将return_buffers 选项设置为true 解决了这个问题。

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

更多详情请见here

【讨论】:

    【解决方案2】:

    我不知道如何存储二进制字符串。

    这是我的解决方法:

    其中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);
    });
    

    这并不理想,因为您必须每次都进行转换,但它似乎有效。

    【讨论】:

    • 请注意,不推荐使用 new Buffer()。使用:Buffer.from('some-data', 'base64');
    【解决方案3】:

    return_buffers 的问题是,当您不使用纯缓冲区数据时,您必须做一些事情将其他缓冲区转换为字符串。虽然detect_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');
    });
    

    【讨论】:

    • 在大多数情况下,base64 是更好的选择,因为它会产生比十六进制更小的消息(以更昂贵的编码为代价)。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      我发现这篇文章解释了这样做的含义,我强烈建议在走这条路之前阅读这篇文章(不管编程语言如何)。

      http://qnimate.com/storing-binary-data-in-redis/

      总而言之,由于 Redis 是内存中的键/值存储,因此明智的做法是不要在 Redis 中存储可能较大的值(例如图像),因为这样会很快耗尽可用内存并降低 Redis 实例的性能。最好将文件的位置存储在 Redis 中,而不是文件本身。

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-19
          • 2016-12-09
          • 2013-11-30
          • 1970-01-01
          相关资源
          最近更新 更多