Как запустить асинхронную функцию для каждой строки очень большого (> 1 ГБ) файла в Node.js

Допустим, у вас есть огромный (> 1 ГБ) CSV идентификаторов записей:

655453
4930285
493029
4930301
493031
...

И для каждого идентификаторавы хотите сделать вызов REST API, чтобы получить данные записи, преобразовать их локально и вставить в локальную базу данных.

Как вы делаете это с Readable StreamNode.js?

Мой вопрос в основном заключается в следующем: как вы читаете очень большой файл, построчно, запускаете асинхронную функцию для каждой строки и [необязательно] можете начать чтение файла с определенной строки?

Из следующего вопроса Quora я начинаю учиться использовать fs.createReadStream:

http://www.quora.com/What-is-the-best-way-to -read-a-file-line-by-line-in-node-js

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

var stream = fs.createReadStream(path, {
  flags: 'r',
  encoding: 'utf-8'
});

new lazy(stream).lines.forEach(function(line) {
  var id = line.toString();
  // pause stream
  stream.pause();
  // make async API call...
  makeAPICall(id, function() {
    // then resume to process next id
    stream.resume();
  });
});

Но этот псевдокод не работает, потому чтоленивыймодульзаставляет вас читать весь файл (как поток, но без паузы). Так что этот подход, похоже, не сработает.

Другое дело, хотелось бы иметь возможность запускать обработку этого файла с определенной строки. Причина этого в том, что обработка каждого id(вызов API, очистка данных и т. д.) может занимать до полсекунды на запись, поэтому я не хочу начинать с начало файла каждый раз. Наивный подход, который я думаю об использовании, состоит в том, чтобы просто захватить номер строки последнего обработанного идентификатора и сохранить его.Затем, когда вы снова анализируете файл, вы просматриваете все идентификаторы, строка за строкой, пока не найдете номер строки, на которой остановились, а затем выполняете дело makeAPICall. Другой наивный подход состоит в том, чтобы писать небольшие файлы (скажем, из 100 идентификаторов) и обрабатывать каждый файл по одному (достаточно маленький набор данных, чтобы делать все в памяти без потока ввода-вывода). Есть лучший способ сделать это?

Я вижу, насколько это сложно (и где node-lazyпоявляется), потому что чанкв stream.on('data', function(chunk) {});может содержать только частьстроки (если bufferSize мал, каждый фрагмент может состоять из 10 строк, но поскольку idимеет переменную длину, он может содержать только быть 9,5 строк или что-то еще). Вот почему мне интересно, как лучше всего подойти к вышеуказанному вопросу.

6
задан Lance Pollard 18 June 2012 в 07:07
поделиться