我有一个需要重定向请求的http服务,我没有使用流,因为我处理multipart中的大文件,它压倒了RAM或磁盘(见
How do Node.js Streams work?)
现在我使用管道,它的工作原理,代码是这样的:
var Req = getReq(response);
request.pipe(Req);
唯一的缺点是,在这个多部分中,我在管道中重新发送包含一个需要更改几个字段的JSON文件.
我仍然可以使用管道并更改管道多部分中的一个文件吗?
最佳答案 您可以使用
Transform Stream执行此操作.
var Req = getReq(response);
var transformStream = new TransformStream();
// the boundary key for the multipart is in the headers['content-type']
// if this isn't set, the multipart request would be invalid
Req.headers['content-type'] = request.headers['content-type'];
// pipe from request to our transform stream, and then to Req
// it will pipe chunks, so it won't use too much RAM
// however, you will have to keep the JSON you want to modify in memory
request.pipe(transformStream).pipe(Req);
转换流代码:
var Transform = require('stream').Transform,
util = require('util');
var TransformStream = function() {
Transform.call(this, {objectMode: true});
};
util.inherits(TransformStream, Transform);
TransformStream.prototype._transform = function(chunk, encoding, callback) {
// here should be the "modify" logic;
// this will push all chunks as they come, leaving the multipart unchanged
// there's no limitation on what you can push
// you can push nothing, or you can push an entire file
this.push(chunk);
callback();
};
TransformStream.prototype._flush = function (callback) {
// you can push in _flush
// this.push( SOMETHING );
callback();
};
在_transform函数中,您的逻辑应该是这样的:
>如果在当前块中,您要修改的JSON开始
< SOME_DATA_BEFORE_JSON> < MY_JSON_START>
然后this.push(SOME_DATA_BEFORE_JSON);并将MY_JSON_START保存在本地var中
>当您的JSON尚未结束时,将块添加到您的本地var
>如果在当前块中,JSON结束:
< JSON_END> < SOME_DATA_AFTER_JSON>
然后将JSON_END添加到您的var中,执行您想要的任何更改,
并推动更改:
this.push(local_var);
this.push(SOME_DATA_AFTER_JSON);
>如果当前的块没有任何JSON,只需按下块即可
this.push(块);
除此之外,您可能需要阅读multipart format.
上面的SOME_DATA_BEFORE_JSON将是:
--frontier
Content-Type: text/plain
<JSON_START>
除了Content-Type,它可能包含文件名,编码等.
有些事情要记住,块可能会在任何地方结束(可能在边界中间结束).
解析可能会非常棘手;我会搜索边界键(边界),然后检查JSON是否在此之后启动.会有两种情况:
> chunk:< SOME_DATA> –frontier< FILE METADATA> < FILE_DATA>
>块1:< SOME_DATA> –fron
块2:ier< FILE METADATA> < FILE_DATA>
希望这可以帮助!