Как читать очень большие (> 1 ГБ) файлы tar.gz в Node.js?

Мне никогда не приходилось делать это раньше, так что это, вероятно, что-то действительно основное, но я думал, что я все равно спрошу.

Каков правильный способ чтения очень большого файла в Node.js? Скажите, что файл слишком большой, чтобы читать все сразу. Также скажите, что файл может входить в формате .zip или .tar.gz.

Первый вопрос: лучше ли сначала распаковать файл и сохранить его на диск (я использую Stuffit на Mac для этого сейчас), а затем работать с этим файлом? Или вы можете прочитать поток IO прямо из сжатой версии .zip или .tar.gz? Я думаю, вам нужно знать формат содержимого в сжатом файле, поэтому вам, вероятно, придется распаковать (только что узнал, что этот файл .tar.gz самом деле является файлом .dat)...

Тогда основная проблема заключается в том, как я могу прочитать этот большой файл в Node.js? Скажите, что это 1GB XML файл, где я должен искать, чтобы начать его разбор? (Нет, как разбирать XML, но если вы читаете большой файл по очереди, как вы разбираете что-то вроде XML, которому нужно знать контекст предыдущих строк).

Я видел fs.createReadStream, но я боюсь обходиться с ним... не хочу взорвать мой компьютер. Просто ищите некоторые указатели в правильном направлении.

Ответ 1

существует встроенный модуль zlib для декомпрессии потока и sax для анализа XML потока

var fs = require('fs');
var zlib = require('zlib');
var sax = require('sax');

var saxStream = sax.createStream();
// add your xml handlers here

fs.createReadStream('large.xml.gz').pipe(zlib.createUnzip()).pipe(saxStream);

Ответ 2

Мы также можем закрепить каталог следующим образом:

var spawn = require('child_process').spawn;
var pathToArchive = './very_large_folder.tar.gz';
var pathToFolder = './very_large_folder';

var tar = spawn('tar', ['czf', pathToArchive, pathToFolder]);
tar.on('exit', function (code) {
        if (code === 0) {
                console.log('completed successfully');
        } else {
                console.log('error');
        }
});

Это сработало красиво :)