【问题标题】:How to store the readStream files of Node.js into Redis and also how to retrieve the stored readStream files from Redis?如何将 Node.js 的 readStream 文件存储到 Redis 中,以及如何从 Redis 中检索存储的 readStream 文件?
【发布时间】:2021-08-22 19:00:48
【问题描述】:

我尝试将 readStream (Image) 转换为字符串,然后将其存储在 Redis 中。然后从 Redis 中检索字符串并将其转换回 readStream。但没有成功。

function getFile(fileKey) {
  console.log(fileKey);
  const downloadParams = {
    Key: fileKey,
    Bucket: bucketName,
  };

  return s3.getObject(downloadParams).createReadStream();
}

exports.getFile = getFile;

为了将流转换为字符串,我使用的是流到字符串。它被转换并存储在 Redis 中。

const { getFile } = require("../s3");
const redis = require("redis");

const client = redis.createClient();

var toString = require("stream-to-string");

exports.getFileFromS3Controller = async (req, res) => {
  console.log(req.params);
  const path = req.params.path;
  const key = req.params.key;
  const readStream = getFile(path + "/" + key);

  toString(readStream).then(function (msg) {
    // Set data to Redis
    client.setex(key, 3600, msg);
  });

  readStream.pipe(res);
};

在从 Redis 中检索时,我没有得到它。

const redis = require("redis");
const client = redis.createClient(null, null, { detect_buffers: true });
const Readable = require("stream").Readable;

// Cache middleware
function cache(req, res, next) {
  const { path, key } = req.params;

  client.get(key, (err, data) => {
    if (err) throw err;

    if (data !== null) {
      var s = new Readable();
      s.push(data);
      s.push(null);
      s.pipe(res);
    } else {
      next();
    }
  });
}

router.get("/:path/:key", cache, getFileFromS3Controller);

【问题讨论】:

    标签: node.js redis node-redis nodejs-stream redis-cache


    【解决方案1】:

    你没有打电话给下一个。另一个错误是流没有保存在 req 中的任何位置,因此您可以稍后从控制器访问。据我所知,您直接在 res 中编写它是一个问题,因为在此之后您不能再使用 res 发送任何其他内容。

    这是代码(未测试)

    exports.getFileFromS3Controller = (req, res) => {
      if (req.fileStream) {
          req.fileStream.pipe(res);
          return
      }
    
      console.log(req.params);
      const path = req.params.path;
      const key = req.params.key;
      const readStream = getFile(path + "/" + key);
    
      toString(readStream).then(function (msg) {
          // Set data to Redis
          client.setex(key, 3600, msg);
    
          // Conver string to readable
          const readable = new Readable();
          readable.push(msg);
          readable.push(null);
          readable.pipe(res);
      });
    };
    
    function cache(req, res, next) {
        const { path, key } = req.params;
    
        client.get(key, (err, data) => {
            if (err) throw err;
    
            if (data !== null) {
                var s = new Readable();
                s.push(data);
                s.push(null);
    
                req.fileStream = s;
            }
    
            next();
        });
    }
    

    编辑我修正了答案中的一个错误,因为可读流无法倒带。

    【讨论】:

    • 我纠正了您指出的错误,但检索时仍然没有显示图像。
    • @ShakkirMoulana 请再试一次,因为我忽略了与 Readable 相关的细节。还要确保 getFile 是同步的。如果是 Promise 或 async 函数,则必须等待。
    • 我又试了一次,还是不行。如果我使用 readStream.pipe(res),我会得到图像。但是在将 readStream 转换为字符串然后转换回可读之后,它不起作用。我认为转换部分存在一些问题。
    • 您的意见对我有帮助。谢谢你。我没有将字符串转换为流,反之亦然,而是使用了 redis-wstream 和 redis-rstream 模块。它现在正在工作。
    • @ShakkirMoulana 如果我的回答有帮助,请接受。
    猜你喜欢
    • 2019-05-15
    • 2019-01-11
    • 2019-08-20
    • 2020-04-30
    • 2017-07-04
    • 1970-01-01
    • 2017-11-19
    • 2020-12-03
    • 2020-03-25
    相关资源
    最近更新 更多