我写了一个简单的脚本来从CDN下载视频文件,其中直接URL很容易生成,例如 http://something.com/N.mp4,其中N是数字. 问题是,当下载大于300MB的文件时,文件完全出现在硬盘驱动器中,但在请求(…
问题是,当下载大于300MB的文件时,文件完全出现在硬盘驱动器中,但在请求(…)的回调之前,会发生内存分配失败:
FATAL ERROR: CALL_AND_RETRY_0 Allocation failed - process out of memory
这是否因为一些严重的不良做法而发生?可以请求下载此大小的媒体文件吗?
环境:Win7,4GB可用RAM,节点v0.10.31
var request = require('request'); var async = require('async'); var fs = require('fs'); var start = +process.argv[2] || 1; var end = +process.argv[3] || 50; var url = 'http://something.com/'; try { fs.mkdirSync(__dirname + '/videos/'); } catch (e) {} var index = start; async.whilst( function () { return index <= end; }, function (callback) { var fileName = index + '.mp4'; console.log('Started: ' + fileName); console.time('Done (' + fileName + ')'); request(url + fileName, function() { console.timeEnd('Done (' + fileName + ')'); index++; callback(null); }).pipe(fs.createWriteStream(__dirname + '/videos/' + fileName)); }, function (err) { if (err) { return console.error(err); } console.log('Script finished.'); } );
控制台输出示例:
> node index.js 3 Started: 3.mp4 Done (3.mp4): 296592ms Started: 4.mp4 Done (4.mp4): 369718ms Started: 5.mp4 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed - process out of memory如果您使用带有回调的请求模块,它会将整个响应主体缓冲在内存中.尝试省略回调并使用fs stream的finish事件.
var writer = fs.createWriteStream(__dirname + '/videos/' + fileName); writer.on('finish', function() { // ... index++; callback(null); }); request(url + fileName).pipe(writer);