如何编写 Node.js 模块来处理传入的管道流
How do I write a Node.js module to handle an incoming piped stream
我正在尝试编写一个接受传入管道二进制(或base-64编码)流的节点模块,但坦率地说,我什至不知道从哪里开始。我在 Node 文档中看不到任何关于处理传入流的示例;我只看到消费它们的例子?
例如,假设我希望能够做到这一点:
var asset = new ProjectAsset('myFile', __dirname + '/image.jpg')
var stream = fs.createReadStream(__dirname + '/image.jpg', { encoding: 'base64' }).pipe(asset)
stream.on('finish', function() {
done()
})
我ProjectAsset
看起来像这样,但我不知道下一步该去哪里:
'use strict'
var stream = require('stream'),
util = require('util')
var ProjectAsset = function() {
var self = this
Object.defineProperty(self, 'binaryData', {
configurable: true,
writable: true
})
stream.Stream.call(self)
self.on('pipe', function(src) {
// does it happen here? how do I set self.binaryData?
})
return self
}
util.inherits(ProjectAsset, stream.Stream)
module.exports = ProjectAsset
module.exports.DEFAULT_FILE_NAME = 'file'
可以从stream.Stream
继承并使其工作,但是根据文档中提供的内容,我建议从stream.Writable
继承。管道进入stream.Writable
您需要定义_write(chunk, encoding, done)
来处理管道。下面是一个示例:
var asset = new ProjectAsset('myFile', __dirname + '/image.jpg')
var stream = fs.createReadStream(__dirname + '/image.jpg', { encoding: 'base64' }).pipe(asset)
stream.on('finish', function() {
console.log(asset.binaryData);
})
项目资产
'use strict'
var stream = require('stream'),
util = require('util')
var ProjectAsset = function() {
var self = this
self.data
self.binaryData = [];
stream.Writable.call(self)
self._write = function(chunk, encoding, done) {
// Can handle this data however you want
self.binaryData.push(chunk.toString())
// Call after processing data
done()
}
self.on('finish', function() {
self.data = Buffer.concat(self.binaryData)
})
return self
}
util.inherits(ProjectAsset, stream.Writable)
module.exports = ProjectAsset
module.exports.DEFAULT_FILE_NAME = 'file'
如果您还希望从stream
中读取,请查看从stream.Duplex
继承以及包括_read(size)
方法。
如果你正在做一些更简单的事情,还有简化的构造函数 api。
我不确定这是否是您要查找的,但我认为您可以使用缓冲区 Buffer.concat
API 来处理它,并在可以在流data
侦听器上从chunk
检索的缓冲区数组
'use strict'
var stream = require('stream'),
util = require('util');
var ProjectAsset = function() {
var self = this
Object.defineProperty(self, 'binaryData', {
configurable: true,
writable: true
})
stream.Stream.call(self)
var data;
var dataBuffer=[];
self.on('data', function(chunk) {
dataBuffer.push(chunk);
}).on('end',function(){
data=Buffer.concat(dataBuffer);
});
self.binaryData=data.toString('binary');
return self
}
util.inherits(ProjectAsset, stream.Stream)
module.exports = ProjectAsset
module.exports.DEFAULT_FILE_NAME = 'file'
既然你使用var asset = new ProjectAsset('myFile', __dirname + '/image.jpg')
我想你的项目资产职责是采取一些输入流做一些转换并将其写入文件。您可以实现转换流,因为您从流接收一些输入,并生成一些可以保存到文件或其他写入流的输出。
当然,您可以通过从节点继承来实现转换流.js但继承非常麻烦,所以我的实现使用 through2 来实现转换流:
module.exports = through2(function (chunk, enc, callback) {
// This function is called whenever a piece of data from the incoming stream is read
// Transform the chunk or buffer the chunk in case you need more data to transform
// Emit a data package to the next stream in the pipe or omit this call if you need more data from the input stream to be read
this.push(chunk);
// Signal through2 that you processed the incoming data package
callback();
}))
用法
var stream = fs.createReadStream(__dirname + '/image.jpg', { encoding: 'base64' })
.pipe(projectAsset)
.pipe(fs.createWriteStream(__dirname + '/image.jpg'));
如此示例所示,实现流管道完全分离数据转换和数据保存。
工厂功能
如果您更喜欢在项目资产模块中使用类似构造函数的方法,因为您需要传递一些值或内容,则可以轻松导出构造函数,如下所示
var through2 = require('through2');
module.exports = function(someData) {
// New stream is returned that can use someData argument for doing things
return through2(function (chunk, enc, callback) {
// This function is called whenever a piece of data from the incoming stream is read
// Transform the chunk or buffer the chunk in case you need more data to transform
// Emit a data package to the next stream in the pipe or omit this call if you need more data from the input stream to be read
this.push(chunk);
// Signal through2 that you processed the incoming data package
callback();
});
}
用法
var stream = fs.createReadStream(__dirname + '/image.jpg', { encoding: 'base64' })
.pipe(projectAsset({ foo: 'bar' }))
.pipe(fs.createWriteStream(__dirname + '/image.jpg'));
- 可以't让我的if语句处理js中的html表单输入
- keyup事件处理程序更改焦点不适用于快速键入
- 如何使用jquery处理php循环通过元素
- 如何检查管道中未定义的项目
- angular.js没有'无法在PhoneGap中处理视图标记
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- 提示使用服务器端事件处理程序激活JavaScript
- javascript:如何在antlr生成的Lexer中进行错误处理
- 如何编写一个具有公共标头的批处理
- 在同一个服务工作者中处理service-worker.js有任何影响吗
- 如何处理node.js节点mongodb中的连接和查询队列
- 通过命令行/批处理文件打开页面时,将javascript代码注入Google Chrome
- 如何处理10页以上的静态页眉/页脚
- 将事件处理程序绑定到任何可能的事件
- 通过ajax将坐标传递到php服务器端,并在处理后检索到javascript
- 请求管道处理错误
- 如何编写 Node.js 模块来处理传入的管道流
- 异步库是否有任何用于处理管道的控制流
- 如何处理大文件、NodeJS流和管道
- 用lodash对管道进行过滤和处理