Javascript 通过gm使用Express.js上传流文件,以消除重复写入

Javascript 通过gm使用Express.js上传流文件,以消除重复写入,javascript,node.js,express,graphicsmagick,Javascript,Node.js,Express,Graphicsmagick,我使用的是Express.js,有一个上传图像的路径,然后需要调整大小。目前我只是让Express将文件写入磁盘(我认为在封面下使用node),然后使用gm调整大小(http://aheckmann.github.com/gm/)将第二个版本写入磁盘 gm(path) .resize(540,404) .write(dest, function (err) { ... }); 我已经读到,您可以在节点将文件流写入磁盘之前获得它,并且由于gm可以接受一个流而不仅仅是一个路径,因此我应该能

我使用的是
Express.js
,有一个上传图像的路径,然后需要调整大小。目前我只是让
Express
将文件写入磁盘(我认为在封面下使用
node
),然后使用
gm
调整大小(http://aheckmann.github.com/gm/)将第二个版本写入磁盘

gm(path)
  .resize(540,404)
  .write(dest, function (err) { ... });
我已经读到,您可以在
节点将文件流写入磁盘之前获得它,并且由于
gm
可以接受一个流而不仅仅是一个路径,因此我应该能够通过消除对磁盘的双重写入来正确传递这一点

我想我需要覆盖
表单.onPart
,但我不确定在哪里(应该作为
Express
中间件来完成),我也不确定如何获得
表单
或者如何处理
部分
。这是我在几个地方看到的代码框架:

form.onPart = function(part) {
    if (!part.filename) { form.handlePart(part); return; }

    part.on('data', function(buffer) {

    });
    part.on('end', function() {

    }
}

有人能帮我把这两块拼合起来吗?谢谢

通过重写
form.onPart
,您走上了正确的道路。默认情况下,对磁盘的写操作非常强大,因此您希望在它之前采取行动

零件本身就是流,因此您可以通过管道将它们输送到任何您想要的地方,包括
gm
。我还没有对其进行测试,但根据文档,这是有意义的:

var form = new formidable.IncomingForm;
form.onPart = function (part) {
  if (!part.filename) return this.handlePart(part);

  gm(part).resize(200, 200).stream(function (err, stdout, stderr) {
    stdout.pipe(fs.createWriteStream('my/new/path/to/img.png'));
  });
};
至于中间件,我将从Connect/Express复制粘贴
multipart
中间件,并向其添加
onPart
功能:


如果
强大的
在默认情况下不写入磁盘,或者如果它带有一个标志,会更好,不是吗?您可以给他们发一期。

谢谢!这让我有了95%的成功。我的最后一个问题是
gm
是异步的,因此表单解析在调整大小实际完成之前返回(这意味着我返回到客户端的url还不太好)。有没有办法让
强大的
知道
部分
的处理何时实际完成?实际上,我只是在客户端处理了这个问题-这样做效果更好。再次感谢!stdout是一条小溪。这就是为什么可以通过管道()将其传输到文件写入流。这意味着它有一个“结束”的事件,你可以听。只要执行stdout.on('end',fn),就可以告诉客户任务完成了。