Не могу распаковать файл, сгенерированный нод-архиватором на OSx - PullRequest
1 голос
/ 25 марта 2019

Я создаю сжатый файл на основе данных JSON. В настоящее время, когда я генерирую файл TAR, мой API работает просто отлично. Вот мой код:

app.post('/', (req, res) => {
  const filename = 'export.tar';

  const archive = archiver('tar', {});

  archive.on('warning', (err) => {
    console.log(`WARN -> ${err}`);
  });

  archive.on('error', (err) => {
    console.log(`ERROR -> ${err}`);
  });

  const files = req.body.files || [];
  for (const file of files) {
    archive.append(file.content, { name: file.name });
    console.log(`Appending ${file.name} file: ${JSON.stringify(file, null, 2)}`);
  }

  try {
    if (files.length > 0) {
      archive.pipe(res);
      archive.finalize();
      return res.attachment(filename);
    } else {
      return res.send({ error: 'No files to be downloaded' });
    }
  } catch (e) {
    return res.send({ error: e.toString() });
  }
});

А вот пример JSON, через который я прохожу:

{
  "title": "Sample Title",
  "files": [
    {
      "name": "index.html",
      "content": "<p>Hello, World!</p>"
    },
    {
      "name": "README.md",
      "content": "# Hello, World!"
    }
  ]
}

Но, когда я изменяю это для создания ZIP-файла, я получаю сообщения об ошибках типа 21 «Является ли каталог» или 2 «Нет такого файла или каталога».

Код, который я изменил:

  const filename = 'export.zip';
  const archive = archiver('zip', {
    zlib: { level: 9 },
  });

Я пытался посмотреть на другие вопросы и проблемы, но мне не повезло, когда я делал store: true или двигался finalize(), или делал forceZip64: true. Что можно изменить для корректной работы ZIP-файлов?

1 Ответ

0 голосов
/ 26 марта 2019

Это сделал трюк! Создав выходные данные с помощью createWriteStream, а затем отправив туда архив, мы можем загрузить zip-файл, который отлично работает.

app.post('/', (req, res) => {
  const filename = 'export.zip';

  const archive = archiver('zip', {});

  let output = fs.createWriteStream(filename);

  archive.on('warning', err => {
    console.log(`WARN -> ${err}`);
  });

  archive.on('error', err => {
    console.log(`ERROR -> ${err}`);
  });

  output.on('end', function() {
    console.log('Data has been drained');
  });
  archive.pipe(output);

  const files = req.body.files || [];
  for (const file of files) {
    archive.append(file.content, { name: file.name });
    console.log(`Appending ${file.name} file: ${JSON.stringify(file, null, 2)}`);
  }

  try {
    if (files.length > 0) {
      archive.finalize();
      res.download(filename);
    } else {
      return res.send({ error: 'No files to be downloaded' });
    }
  } catch (e) {
    return res.send({ error: e.toString() });
  }
});
...