Nodejs,如何在没有崩溃的情况下复制nodejs中的多个文件

时间:2014-04-30 20:56:36

标签: node.js http stream file-copying

我尝试使用节点js复制多个文件。

以下是我尝试做的一个例子:

var request = require('request');
 va photos [{ 'url': 'http://xxxx.com/im1', 'name' : 'name1' }, { 'url': 'http://xxxx.com/im12', 'name' : 'name2'    }, 
 for (var i = 0; i < photos.length; i++) {
                        request(photos[i].source).pipe(fs.createWriteStream(photos[i].name));
  }

在1000次通话后,我有一个套接字挂出错误。

根据@Timothy Strimple的建议,我决定使用异步模块。

我的代码现在是这样的:

async.whilst(function () { return !stop; },
                function (callback) {
                    console.log("get next 20 image");
                    JM.api('/' + album.id + '/photos', { after: next }, function (resf) {
                        if (!resf || resf.error) {
                            console.log(!resf ? 'error occurred' : resf.error);
                        }
                        console.log("albums" + album.id + " " + resf.data.length + " dir" + dir);

                        async.eachSeries(resf.data, function (photo, done) {

                            request(photo.source).pipe(fs.createWriteStream(dir + "/" +photo.name));
                            console.log("copy of image " + img_basename);
                        }, function (err) {
                            if (err) {
                                console.log('An images failed to copy');
                            } else {
                                console.log('All 20 image have been copied successfully');
                            }
                            if (resf.paging && resf.paging.cursors) {
                                console.log("suite de l'album à venir");
                                next = resf.paging.cursors.after;
                                setTimeout(function () { callback(); }, 5000);
                            }
                            else {
                                console.log("Fin de l'album");
                                stop = true;
                                setTimeout(function () { callback(); }, 5000);
                            }
                        });
                    });
                },
                function (err) {
                    if (err) {
                        console.log('An images failed to process');
                        albumcallback();
                    } else {
                        console.log('All images in this group have been processed successfully');
                        albumcallback();
                    }
                }
            );// end while

我可能在复制了100个文件后崩溃了。我确定async.whilst和async.eachSeries是weel,因为我的日志显示每个调用都是串行的。但我崩溃了。我通过在每个副本之后等待等待来暂时解决问题:

request(photo.source).pipe(fs.createWriteStream(dir + "/" + img_basename));
                            console.log("copy of image " + img_basename);
                            setTimeout(function () { done(); }, 5000);

是请求模块的限制吗?如何更改此功能以确保在继续执行程序之前关闭每个连接?

2 个答案:

答案 0 :(得分:2)

您可能需要转到异步循环。 <{3}}模块中eachLimit之类的东西可能是理想的。

async.eachLimit(photos, 10, function(photo, done) {
    var r = request(photos[i].source).pipe(fs.createWriteStream(photos[i].name));
    r.on('finish', done);
}, function(err) {
    // All images done or there was an error
});

现在它将处理照片列表中的所有项目,但它只会同时处理其中的10个项目。这将阻止它启动数百或数千个并发传出连接。

答案 1 :(得分:0)

请求调用和管道调用是asyncrhon。所以我必须重写这一行:request(photos [i] .source).pipe(fs.createWriteStream(photos [i] .name));

见这里: Downloading N number of remote files using Node.js synchronously