Как правильно загрузить ZIP-файл, используя Node Js, Archiver и Express

Я пытаюсь сжать содержимое двух каталогов и загрузить полученный ZIP-файл. Один каталог содержит файлы.txt, а другой -.jpg. Я использую архиватор для архивирования файлов и запускаю экспресс-фреймворк на узле js. Я склонен думать, что проблема существует на этапе загрузки, так как результирующий архивированный файл, который создается в корне проекта, расширяется, как и ожидалось, однако, когда файл загружается, я получаю "Ошибка 2 - Нет такого файла или каталога. "

    app.get('/download',function(req, res){

        zipFile = new Date() + "-Backup.zip";

        var output = fs.createWriteStream(__dirname +"/backups/"+ zipFile);
        var archive = archiver('zip');

        output.on('close', function() {
            console.log(archive.pointer() + ' total bytes');
            console.log('archiver has been finalized and the output file descriptor has closed.');
        });

        archive.on('error', function(err) {
            throw err;
        });

        archive.pipe(output);

        var files1 = fs.readdirSync(__dirname+'/posts');
        var files2 = fs.readdirSync(__dirname+'/uploads');
            for(var i = 0; i< files1.length; i++){
                archive.append(fs.createReadStream(__dirname+"/posts/"+files1[i]), { name: files1[i] });
            }
            for(var i = 0; i< files2.length; i++){
                archive.append(fs.createReadStream(__dirname+"/uploads/"+files2[i]), { name: files2[i] });
            }
        archive.finalize(); 
        res.download(__dirname + "/backups/" + zipFile, zipFile); 

    });

zipFile - это глобальная переменная.

Журналы on 'close' запускаются корректно и ошибок не возникает, но файл не откроется после загрузки. Есть ли проблема с заголовками ответа или что-то еще, о чем я не знаю?

Спасибо за помощь.

2 ответа

Я решил свою проблему, используя node-zip в качестве утилиты архивирования.

var zip = require('node-zip')(); // require the node-zip utility
var fs = require('fs'); // I use fs to read the directories for their contents

var zipName = "someArbitraryName.zip"; // This just creates a variable to store the name of the zip file that you want to create
var someDir = fs.readdirSync(__dirname+"/nameOfDirectoryToZip"); // read the directory that you would like to zip
var newZipFolder = zip.folder('nameOfDirectoryToZip'); // declare a folder with the same name as the directory you would like to zip (we'll later put the read contents into this folder)


//append each file in the directory to the declared folder
for(var i = 0; i < someDir.length,i++){
    newZipFolder.file(someDir[i], fs.readFileSync(__dirname+"/nameOfDirectoryToZip/"+someDir[i]),{base64:true});
}

var data = zip.generate({base64:false,compression:'DEFLATE'}); //generate the zip file data

//write the data to file
fs.writeFile(__dirname +"/"+ zipName, data, 'binary', function(err){
    if(err){
        console.log(err);
    }
    // do something with the new zipped file
}

По сути, то, что происходит, можно разбить на 3 этапа:

  1. Используйте fs для чтения содержимого каталога, который вы хотите заархивировать.
  2. Используйте zip.folder, чтобы объявить папку, затем используйте zip.file, чтобы добавить файлы в этот каталог. Я просто использовал цикл for для итеративного добавления каждого файла в каталог, который был прочитан на шаге 1.
  3. Используйте zip.generate для создания данных файла.zip и запишите его в файл с помощью fs.

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

Если вы хотите заархивировать более одного каталога, просто повторите шаги 1 и 2 перед zip.generate, создав новую папку zip.folder для каждого каталога.

Просто используйте

      archive.on("finish",function(){
    res.download(__dirname + "/backups/" + zipFile);
  })
Другие вопросы по тегам