我正在使用node-archiver(https://github.com/archiverjs/node-archiver)在内存上创建一个zip文件。 使用归档程序的管道功能,我将所有内容都管理到变换流。 如果需要,我可以将此流传输到一个文件,但我希望让请求(https://github.com/request)读取此流,所以我不必访问文件系统。Node.js和Requestjs:将一个转换流传输到Request.js作为上传文件
下面,我的转换流被称为bridge
。我没有对Transform做任何特别的处理(我相信它也可能是PassThrough流)。
var archive = archiver('zip');
archive.pipe(bridge);
var r = request.post(url, function(err, res, body){ .... }
var form = r.form();
form.append('token', <some token>);
form.append('file', bridge, { "filename" : "package.zip", "contentType" : "application/zip" });
archive.append(<some string>, { "name": <some file name> });
archive.finalize();
这不起作用(看起来file
部分是空的)。但是,如果我将桥接转换流传输到文件写入流 - 并且在流完成后 - 我在表单文件操作中为该文件创建了一个读取流,它可以工作。当然,因为现在我有一个完全形成文件,并request
可以读取它(我也不会在这里需要一个桥梁,只是普通fs
流)
bridge.pipe(fs.createWriteStream(<myfile>));
var archive = archiver('zip');
archive.pipe(bridge);
bridge.on("finish", function(){
var r = request.post(url, function(err, res, body){ .... }
var form = r.form();
form.append('token', <some token>);
form.append('file', fs.createReadStream(<myfile>), { "filename" : "package.zip", "contentType" : "application/zip" });
}
archive.append(<some string>, { "name": <some file name> });
archive.finalize();
不知request
需要读取数据流是一个文件流 - 还有什么我可以做错在这里。
这是我的恐惧。因此,虽然Request接受一个流(fs.createReadStream),但它从readstream对象获取内容长度。我想知道是否可以在完成时获取存档器内容长度,然后为请求设置此标头。似乎可以通过监听存档器上的关闭事件(类似于http://stackoverflow.com/a/30882016/2020565 - 和/或使用存档器指针https://archiverjs.com/docs /Archiver.html#pointer来累计总字节数 – noderman
在启动HTTP请求之前,你仍然需要知道内容长度,所以我不明白这会有什么帮助,你可以做的一件事是创建一个passthrough stream,带有足够大的highWater标记,将你的zip存储在内存中,然后上传新的流。这在我的情况下是不可能的,因为我期待的流量可能在10GB左右。 – thejinx0r
也许这可能是可能的“将管道归档为空”,获取内容大小和**然后**重做操作,这次使用获取的长度数据设置内容长度。**显然**,这意味着执行归档操作两次,但会避免将所有内容存储在内存中如果有这个选择,我们会很高兴。我会尽力为踢。 – noderman