MongoDB GridFS API возвращает поврежденный .zip - PullRequest
0 голосов
/ 03 июля 2018

Контекст:

Node.js / Loopback-приложение, которое заполняет свою базу данных файлом .zip, содержащим данные из устаревших корпоративных CRM-приложений. Я пытаюсь сохранить двоичный файл .zip-файла в моей базе данных для целей производственной отладки, используя GridFS, поскольку размер файла может превышать 16 МБ, и извлекать его в любое время, используя конечную точку администратора.

Проблема:

Я могу сохранить zip-файл с функцией storeLatestZipFile в своем модуле и получить его с помощью конечной точки, которую создает createLatestZipEndpoint.

Однако .zip, который я получаю, больше, чем оригинальный файл (14,7 МБ против 21,1 МБ), и он также поврежден.

Я предполагаю, что я не кодирую свои данные или просто неправильно использую GridFS API. Может ли кто-нибудь обнаружить ошибки в моем коде / иметь больше опыта в сохранении .zips с GridFS?

Модуль, о котором идет речь:

const { pino } = require('amf-logger');
const fs = require('fs');
const mongo = require('mongodb');

const log = pino({ name: 'bot-zip-upload-storage' });

/**
 * @param {string} path Path to the zip file to be persisted.
 * @param {object} app Loopback application instance.
 */
function storeLatestZipFile(path = './', app = {}) {
  log.info('**** Starting streaming current uploaded zip to DB ****');
  const zipReadStream = fs.createReadStream(path, { encoding: 'binary' });
  const { db } = app.dataSources.mongo.connector;
  const bucket = new mongo.GridFSBucket(db);
  bucket.delete('zipfile', () => {
    log.info('deleted old zipfile');

    const uploadStream = bucket.openUploadStreamWithId(
      'zipfile',
      `bot-data-${new Date().toISOString()}`,
      {
        contentType: 'application/zip'
      }
    );

    zipReadStream.pipe(uploadStream);
  });
}

/**
 * @param {object} app Loopback application instance.
 */
async function createLatestZipEndpoint(app = {}) {
  if (!app.get) {
    log.error("app object does not have 'get' property.");
    return;
  }

  app.get('/api/admin/latestzip', async (req, res) => {
    if (!req.headers.latestfile || req.headers.latestfile !== process.env.ADMIN_LATESTFILE) {
      res.sendStatus(403);
      return;
    }

    try {
      const { db } = app.dataSources.mongo.connector;
      const bucket = new mongo.GridFSBucket(db);
      res.writeHead(200, { 'Content-Type': 'application/zip' });
      const downloadStream = bucket.openDownloadStream('zipfile');
      log.info('download stream opened, begin streaming');
      downloadStream.pipe(res);
    } catch (err) {
      log.error(`error getting zipfile: ${err}`);
      res.sendStatus(500);
    }
  });
}

module.exports = {
  storeLatestZipFile,
  createLatestZipEndpoint
};

1 Ответ

0 голосов
/ 03 июля 2018

Вы пробовали createReadStream без buffer -кодирования?

const zipReadStream = fs.createReadStream(path);

...