zlib gunzip распаковывает разные размеры буфера при каждом запуске одного и того же файла

Я загружаю файл gzip для ежедневного экспорта из базы данных фильмов и распаковываю его с помощью zlib. Когда происходит событие end, я регистрирую длину строки данных, которые я распаковал. Длина каждый раз разная.

Похоже, что данные не полностью распаковываются. Я заметил это, когда начал анализировать JSON, который на самом деле содержит файл. Он будет на полпути к преобразованию каждой строки JSON (каждая строка представляет собой автономный объект json) и взорвется, потому что json будет искажен.

var http = require('http');
var zlib = require('zlib');

var downloadUrl = "http://files.tmdb.org/p/exports/movie_ids_03_01_2018.json.gz";
http.get(downloadUrl, function(response) {
    var fileContents = "";
    var gunzip = zlib.createGunzip();

    gunzip.on('data', function(data) {
        fileContents += data.toString();
    });

    gunzip.on('end', function() {
        console.log(fileContents.length);
    });

    response.pipe(gunzip);
});

Я неправильно использую события gunzip?

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


person Johnathon Sullinger    schedule 02.03.2018    source источник


Ответы (1)


Я решил это, заменив использование http на request. Я не уверен, что я делал неправильно с http.get, но передача gunzip в возвращаемое значение request решила мою проблему.

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

var downloadUrl = "http://files.tmdb.org/p/exports/movie_ids_03_01_2018.json.gz";
var response = request(downloadUrl);
var fileContents = "";
var gunzip = zlib.createGunzip();

gunzip.on('data', function(data) {
    fileContents += data.toString();
});

gunzip.on('end', function() {
    var json = fileContents.split('\n').filter(function(value, index) {
        if (value == "") {
            console.log(index + " is empty and skipped.");
            return false;
        }

        return true;
    });
});

response.pipe(gunzip);

Я пытался использовать request.get(options, function(error, response, body){});, но не смог передать gunzip в ответ или тело. Я новичок в потоках, и мне нужно больше исследовать, чтобы выяснить, что не так. В то же время решение выше работает без проблем.

Поскольку это запускается один раз в день как функция Azure, синхронный запуск, как это, не имеет большого значения. Я не блокирую дальнейшую работу.

person Johnathon Sullinger    schedule 04.03.2018