【问题标题】:How to chain write stream, immediately with a read stream in Node.js 0.10?如何在 Node.js 0.10 中立即使用读取流链接写入流?
【发布时间】:2013-06-10 12:10:48
【问题描述】:

以下行将从指定的url 变量下载图像文件:

var filename = path.join(__dirname, url.replace(/^.*[\\\/]/, ''));
request(url).pipe(fs.createWriteStream(filename));

这些行将获取该图像并保存到 MongoDB GridFS:

 var gfs = Grid(mongoose.connection.db, mongoose.mongo);
 var writestream = gfs.createWriteStream({ filename: filename });
 fs.createReadStream(filename).pipe(writestream);

像这样链接pipe 会引发错误:500 无法管道。不可管道。

request(url).pipe(fs.createWriteStream(filename)).pipe(writestream);

这是因为图像文件还没有准备好读取,对吧?我应该怎么做才能解决这个问题?错误:500 无法管道。不可管道。

使用以下:Node.js 0.10.10mongooserequestgridfs-stream 库.

【问题讨论】:

    标签: node.js stream mongoose pipe gridfs


    【解决方案1】:

    您不能将 ReadStream 链接到 WriteStream,因为后者不是双工的,因此您可以这样做 - 对于 gzip 压缩的存档

    request.get(url, {
            gzip: true,
            encoding: null
        })
        .pipe(fs.createWriteStream(tmpPath))
        .on('close', function() {
            console.info("downloaded %s", tmpPath);
            fs.createReadStream(tmpPath)
                .pipe(gunzip)
                .pipe(fs.createWriteStream(destPath))
                .on('close', function() {
                    console.info("unarchived %s", destPath);
                })
                .on('error', (error) => {
                    console.warn("gzip error:%@", error);
                })
        })
        .on('error', (error) => {
            console.warn("download error:%@", error);
        })
    

    【讨论】:

      【解决方案2】:

      我认为链接管道的混乱是由于管道方法隐含地自行“做出选择”来返回什么。那就是:

      readableStream.pipe(writableStream) // Returns writable stream
      readableStream.pipe(duplexStream) // Returns readable stream
      

      但一般规则是“您只能通过管道将可写流传输到可读流”。换句话说,只有 Readable Streams 有 pipe() 方法。

      【讨论】:

      • 那么这里发生了什么?在npm axios 文档中它说; response.data.pipe(fs.createWriteStream('path-to-file)) 我们知道请求是可读流,响应是可写流,你说只有可读流有 pipe() 方法,但这里我们直接使用管道将可写流传输到新的 writestream,不涉及读取流。这可能表明管道方法也可用于可写流。
      • @AmmarBayg 我在 2 年前写过这篇文章,与 npm 0.10 版有关。你也检查过那个版本吗?
      【解决方案3】:
      // create 'fs' module variable
      var fs = require("fs");
      
      // open the streams
      var readerStream = fs.createReadStream('inputfile.txt');
      var writerStream = fs.createWriteStream('outputfile.txt');
      
      // pipe the read and write operations
      // read input file and write data to output file
      readerStream.pipe(writerStream);
      

      【讨论】:

      • 实际上恰恰相反:将可读流通过管道传输到可写流。
      【解决方案4】:
      request(url).pipe(fs.createWriteStream(filename)).pipe(writestream);
      

      和这个是一样的:

      var fileStream = fs.createWriteStream(filename);
      request(url).pipe(fileStream);
      fileStream.pipe(writestream);
      

      所以问题是您正试图将.pipe 一个WriteStream 转换为另一个WriteStream

      【讨论】:

      • 是的,您只能从可读或不可写的双工流中读取。见github.com/joyent/node/pull/4843。要链接管道,流需要是双工的,即可读和可写
      猜你喜欢
      • 2018-03-03
      • 1970-01-01
      • 2020-02-28
      • 2015-05-03
      • 2016-06-04
      • 2014-03-13
      • 1970-01-01
      • 2020-06-28
      • 2019-01-24
      相关资源
      最近更新 更多