【问题标题】:How to pass a Buffer as argument of fs.createReadStream如何将缓冲区作为 fs.createReadStream 的参数传递
【发布时间】:2017-08-26 01:53:35
【问题描述】:

根据文档 https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

fs.createReadStream() 可以接受 Buffer 作为第一个参数

我的节点代码:

var _ = require('lodash')
var faker = require('faker')
var http = require('http')
var fs = require('fs')
var xlsx = require('node-xlsx')

var gg = _.range(10).map((item) => {
  return _.range(10).map((item) => {
    return faker.name.findName()
  })
})

http.createServer(function(req, res) {
  var buf = xlsx.build([{
    name: 'sheet1',
    data: gg
  }])
  fs.createReadStream(buf, 'binary').pipe(res)

}).listen(9090)

但我收到此错误:

events.js:160
  throw er; // Unhandled 'error' event
  ^

Error: Path must be a string without null bytes
at nullCheck (fs.js:135:14)
at Object.fs.open (fs.js:627:8)
at ReadStream.open (fs.js:1951:6)
at new ReadStream (fs.js:1938:10)
at Object.fs.createReadStream (fs.js:1885:10)
at Server.<anonymous> (/Users/xpg/project/test/index.js:18:6)
at emitTwo (events.js:106:13)
at Server.emit (events.js:191:7)
at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:546:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)

我只想知道,如果我想传递一个 Buffer 作为路径参数,我应该提供哪些选项,传递 'binary' 是行不通的。

我在 Node 6.11.0 和 Node 8.4.0 上都尝试过

【问题讨论】:

  • 文件路径最终必须是操作系统将接受的字符串,并且不能是随机二进制文件,因此不清楚您通过缓冲区传递的目的是什么。如果你传递一个缓冲区,它大概会在上面调用.toString()
  • @ivo - 该帖子与fs.createReadStream() 的第一个参数无关。
  • 如果Buffer 作为参数传递给fs.createReadStream(),它应该指示文件路径,而不是文件内容。
  • @shaochuancs 能给我看看代码吗?

标签: node.js


【解决方案1】:

fs.createReadStream() 的第一个参数必须是文件路径。您显然可以在 Buffer 对象中传递路径,但当 Buffer 转换为字符串时,它仍然必须是可接受的操作系统路径。

您似乎正在尝试将文件内容传递给fs.createReadStream()。这不是该 API 的工作方式。如果您查看fs.createReadStream() 的代码,则在代码中完全清楚它将调用fs.open() 并将fs.createReadStream() 的第一个参数作为fs.open() 的文件路径传递。

如果您尝试从缓冲区创建可读流(不涉及文件),那么您需要以不同的方式执行此操作。你可以在这个答案中看到如何做到这一点:Converting a Buffer into a ReadableStream in Node.js

从概念上讲,您只需创建一个可读的流对象,将您已有的数据从 Buffer 中推入其中,推入 null 以表示流的结束并创建一个 noop _read() 方法,您就完成了.然后,您可以将该可读流与任何其他希望读取它的代码一起使用。

【讨论】:

    【解决方案2】:

    从缓冲区创建可读流。

    您可以轻松地从缓冲区创建可读流,但是使用 fs.createReadStream() 确实需要首先将其写入文件路径。

    使用 stream.Duplex()

    • 无需编写本地文件即可获得可读流
    • 节省 I/O 并加快速度。
    • 在任何需要 fs.createReadStream() 的地方都可以使用。
    • 非常适合写入本地存储不可行的云服务。

    示例:

    const {Duplex} = require('stream'); // Native Node Module 
    
    function bufferToStream(myBuuffer) {
        let tmp = new Duplex();
        tmp.push(myBuuffer);
        tmp.push(null);
        return tmp;
    }
    
    const myReadableStream = bufferToStream(your_buffer);
    
    // use myReadableStream anywhere you would use a stream 
    // created using fs.createReadStream('some_path.ext');
    // For really large streams, you may want to pipe the buffer into the Duplex.
    

    【讨论】:

    【解决方案3】:

    @jfriend00 已经对这个问题给出了非常清晰的解释。如果 Buffer 对象作为参数传递给 fs.createReadStream(),它应该指示文件路径,而不是文件内容。正如@Littlee 在评论中询问的那样,这是一个示例代码:

    var express = require('express');
    var router = express.Router();
    var fs = require('fs')
    
    router.get('/test', function(req, res) {
      var buf = Buffer.from('./test.html');
      fs.createReadStream(buf).pipe(res);
    });
    

    请注意缓冲区buf 表示文件路径("./test.html"),而不是文件test.html 的内容。

    【讨论】:

      猜你喜欢
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 2017-01-21
      相关资源
      最近更新 更多