如何将Buffer作为fs.createReadStream的参数传递

时间:2017-08-26 01:53:35

标签: node.js

根据文件 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)

enter image description here

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

我尝试使用Node 6.11.0和Node 8.4.0

3 个答案:

答案 0 :(得分:12)

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

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

如果您要做的是从缓冲区创建可读流(不涉及文件),那么您需要以不同的方式执行此操作。您可以在此处查看如何执行此操作:How to wrap a buffer as a stream2 Readable stream?

答案 1 :(得分:2)

@jfriend00已就此问题提供了非常明确的解释。如果将Buffer对象作为参数传递给fs.createReadStream(),则应指示文件路径,而不是文件内容。正如@Littlee在评论中所说,这是一个示例代码:

def xmlString = """<a>    <b>        <c>ccc</c>        <version> 1.0.0</version>        <description> description </description>     </b> </a>"""
def element = 'version'
def newVersion = '2.0.0'
def xml = new XmlParser().parseText(xmlString)
xml.'**'.find{it.name() == element}.replaceNode{"$element" newVersion}
new XmlNodePrinter().print(xml)

请注意,缓冲区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"的内容。

答案 2 :(得分: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.