您的管道如何连接到多个流?

时间:2018-12-24 09:12:06

标签: node.js

我是Node的新手,我正在尝试下载文件,对其进行哈希处理,然后使用哈希作为文件名将其保存到磁盘。我得到的哈希值正确(我认为),但文件为空白。

const fs = require("fs-extra")
const fetch = require("node-fetch")
const crypto = require('crypto')

const response = await fetch(url)
const sha256 = crypto.createHash("sha256")
sha256.setEncoding('hex')
response.body.pipe(sha256)
await new Promise(resolve => response.body.on("end", resolve))
sha256.end()
const hash = sha256.read()
const file = fs.createWriteStream(hash + ".jpg")
response.body.pipe(file)

1 个答案:

答案 0 :(得分:0)

我解决问题的技巧是使用唯一的名称存储文件(使用当前时间戳作为名称),然后您可以对流进行哈希处理(来自响应)并重命名。

我已经测试了这段代码,并且运行良好:

const fs = require("fs-extra")
const path = require('path');
const fetch = require("node-fetch")
const crypto = require('crypto')

const downloadImage = async (url) => {
  try {
    const response = await fetch(url);

    /** Store file with name current timestamp */
    const filename = "IMG_" + Date.now() + ".jpg";
    const dest = path.join(__dirname, filename);
    response.body.pipe(fs.createWriteStream(dest))

    /** Hash file */
    const sha256 = crypto.createHash("sha256")
    sha256.setEncoding('hex')
    response.body.pipe(sha256)
    await new Promise(resolve => response.body.on("end", resolve))
    sha256.end()
    const hash = sha256.read()

    /** Rename file with hash value */
    await fs.rename(dest, path.join(__dirname, hash + ".jpg"))

  } catch (err) {
    console.log(err);
  }
}

const url = "https://i0.wp.com/wptavern.com/wp-content/uploads/2016/07/stack-overflow.png?ssl=1";

downloadImage(url);

但是您可以使用实用程序为哈希流(收到的响应)创建函数,这是我对您的代码的推荐:

const fs = require("fs-extra")
const path = require('path');
const fetch = require("node-fetch")
const crypto = require('crypto')

function streamHash(stream, algorithm = 'md5') {
  return new Promise((resolve, reject) => {
    let shasum = crypto.createHash(algorithm);
    try {
      stream.on('data', function (data) {
        shasum.update(data)
      })
      stream.on('end', function () {
        const hash = shasum.digest('hex')
        return resolve(hash);
      })
    } catch (error) {
      return reject(error);
    }
  });
}

const downloadImage = async (url) => {
  try {
    const response = await fetch(url);

    /** Store file with name current timestamp */
    const filename = "IMG_" + Date.now() + ".jpg";
    const dest = path.join(__dirname, filename);
    response.body.pipe(fs.createWriteStream(dest))

    /** Hash file */
    const hash = await streamHash(response.body, 'sha256');

    /** Rename file with hash value */
    await fs.rename(dest, path.join(__dirname, hash + ".jpg"))

  } catch (err) {
    console.log(err);
  }
}

const url = "https://i0.wp.com/wptavern.com/wp-content/uploads/2016/07/stack-overflow.png?ssl=1";

downloadImage(url);