2015-06-14 3 views
3

Используя nw.js, я просто пытаюсь сохранить изображения в массиве элементов img с разными случайными именами.Ошибка: EMFILE: слишком много открытых файлов

Но имея несколько ошибок, что-то не так с моим кодом?

for (i = 0; i < imgs.length; i++) { 
request(imgs[i].getAttribute('src')).on('error', function(err) { 
    throw err 
}).pipe(fs.createWriteStream('data/imgs/' + randomString)) 
} 

ГИМ [] представляет собой массив 100-500 HTML IMG элемента, но я получаю

Error: EMFILE: too many open files, open *<directory>* 

И другая ошибка:

"Uncaught Error: socket hang up" 

Хотя он сохраняет некоторые изображения, некоторые из них повреждены, и он создает слишком много изображений, чем есть на самом деле.

ответ

6

Используйте модуль graceful-fs, который является заменой модуля fs. Это оболочка вокруг собственного модуля fs. Цитируя docs of graceful-fs module,

Queues up open and readdir calls, and retries them once something closes if there is an EMFILE error from too many file descriptors.

Поскольку он предоставляет тот же API, как родной fs модуль, вы можете использовать его так же, как нормальный fs модуль.

// use just like fs 
var fs = require('graceful-fs'); 

Примечание: Эта библиотека была создана, Исаак З. Schlueter, один из основных разработчиков Node.js.

0

Другим простым решением было бы просто ждать, пока файл будет загружен и только затем открыть новый запрос с помощью рекурсии:

var fs = require('fs'); 
var request = require('request'); 

var dest = '../data/downloads/'; 

function _saveAllFiles (fileUrlArray, curIdx, options) { 
    try { 
     var count = fileUrlArray.length - 1; 
     var curFile = fileUrlArray[curIdx]; 

     var stream = request(curFile) 
      .pipe(fs.createWriteStream(dest + "file_" + curIdx)); 

     stream.on('finish', function() { 
      console.log("Downloaded", curFile); 
      stream.close(); 
      if (curIdx + 1 < count) { 
       //Finished, download next file 
       _saveAllFiles(fileArray, curIdx + 1, options); 
      } 
     }); 
     stream.on('error', function() { 
      console.log("Error", curFile); 
      stream.close(); 
      stream.end(); 
      if (curIdx + 1 < count) { 
       //Error occured, go to next file 
       _saveAllFiles(fileArray, curIdx + 1, options); 
      } 
     }); 
    } catch (err) { 
     console.error("Failed to download file", err); 
    } 
} 
Смежные вопросы