2013-03-01 3 views
2

Итак, у меня есть довольно большой каталог файлов, которые мне нужно обрабатывать постоянно, используя длительный процесс в приложении NodeJS. Каталог постоянно обрабатывается и очищается, но нет ничего необычного в том, что 1000+ файлов должны быть в очереди для обработки в любой момент времени - это файлы CSV с gzipped, поэтому мое наивное решение заключалось в том, чтобы захватить список каталогов, перебрать файлы откройте каждый, анализировать их, а затем продолжить, как это:Как обрабатывать большой (1000+ файлов) каталог файлов с помощью Node.js?

files = fs.readdirSync 'directory' 

for filename in files 
    file_path = path.resolve path.join 'directory', filename 
    fd = fs.openSync file_path, 'r' 
    buf = new Buffer fs.statSync(file_path).size 
    fs.readSync fd, buf, 0, len, 0 
    fs.closeSync fd 
    zlib.gunzip buf, (err, buf) => 
    throw err if err 
    content = buf.toString().split("\n") 
    for line in content 
     # parse, process content, archive file 

Я быстро подбежав против (слишком много открытых файлов) ошибки EMFILE. Пожалуйста, извините версии Sync функций fs и coffeescript.

Есть ли лучший способ обработки массивного количества файлов управляемым способом? В конечном итоге я хотел бы использовать что-то вроде одного синтаксического потока - я знаю, как это сделать с помощью одного большого (или даже растущего) файла, но не с каталогом, полным отдельных файлов.

Файлы генерируются большим количеством несопоставимых клиентов на общедоступный веб-сервер, который затем регулярно синхронизирует их с моим каталогом ввода по защищенному протоколу. Не идеальная настройка, но необходимая с учетом специфики системы, и это объясняет, почему я не могу просто изменить файлы, которые можно сказать, один мультиплексированный поток.

+0

Оформить заказ ['graceful-fs'] (https://npmjs.org/package/graceful-fs). –

ответ

1

Не совсем разбор поток, но может быть шагом на пути к нему:

Вы можете использовать https://npmjs.org/package/generic-pool ограничить де число одновременных файлов в обработке. Вам просто нужно определить, какой ресурс нужно объединить.

В вашем случае я предполагаю, что ресурс для пула должен быть файловым процессором, так что только один или несколько могут жить одновременно.

У вас также может быть какой-то метод итератора, чтобы упорядочить файл, который будет обработан следующим.

EDIT: Завершение моего ответа. Я пробовал об этом и пробовал это https://gist.github.com/Floby/5064222

+0

Работы действительно красиво, спасибо. Асинхронный модуль, который вы используете в этом примере, заботится об основной проблеме, реализуя управляемую параллельную систему очередей (что мне очень нравится, исходя из Obj-C с NSOperationQueue). – HowlingEverett

0

В книге «Узел узла» Mixu есть раздел, посвященный тому, как справиться именно с этим типом проблемы. http://book.mixu.net/node/ch7.html

Вы можете запустить код в «ограниченном параллельно», используя следующий код, как показано здесь - и легко управлять, сколько вы хотите загрузить сразу с параметром предела:

function async(arg, callback) { 
    console.log('do something with \''+arg+'\', return 1 sec later'); 
    setTimeout(function() { callback(arg * 2); }, 1000); 
} 
function final() { console.log('Done', results); } 

var items = [ 1, 2, 3, 4, 5, 6 ]; 
var results = []; 
var running = 0; 
var limit = 2; 

function launcher() { 
    while(running < limit && items.length > 0) { 
    var item = items.shift(); 
    async(item, function(result) { 
     results.push(result); 
     running--; 
     if(items.length > 0) { 
     launcher(); 
     } else if(running == 0) { 
     final(); 
     } 
    }); 
    running++; 
    } 
} 

launcher(); 
Смежные вопросы