简体   繁体   English

如何使用 Node Js、Archiver 和 Express 正确下载 a.zip 文件

[英]How to properly download a .zip file using Node Js, Archiver and Express

I am attempting to zip the contents of two directories and download the resulting.zip file.我正在尝试 zip 两个目录的内容并下载生成的.zip 文件。 One directory contains.txt files and the other.jpg.一个目录包含.txt 文件,另一个目录包含.jpg。 I am using archiver to zip the files and running the express framework on node js.我正在使用归档器来 zip 文件并在节点 js 上运行 express 框架。 I am inclined to think that the problem exists in the download step, as the resulting zipped file that is created in the project root expands as expected, however when the file is downloaded, I get an "Error 2 - No such file or directory."我倾向于认为问题存在于下载步骤中,因为在项目根目录中创建的压缩文件按预期展开,但是当下载文件时,我收到“错误 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 is a global variable. zipFile 是一个全局变量。

The on 'close' logs fire properly and no errors occur, but the file will not open after being downloaded. on 'close' 日志正确触发并且没有发生错误,但文件在下载后不会打开。 Is there an issue with response headers or something else I am unaware of?响应标头或其他我不知道的问题是否存在问题?

Thanks for the help.谢谢您的帮助。

I solved my own problem using node-zip as the archive utility. 我使用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
}

Essentially, what is happening can broken down into 3 steps: 本质上,正在发生的事情可以分为三个步骤:

  1. Use fs to read the contents of a directory that you would like to zip. 使用fs读取您要压缩的目录的内容。
  2. Use zip.folder to declare the folder, then use zip.file to append files to that directory. 使用zip.folder声明文件夹,然后使用zip.file将文件追加到该目录。 I just used a for loop to iteratively add each file in the directory that was read in step 1. 我只是使用了for循环来迭代地将每个文件添加到在步骤1中读取的目录中。
  3. Use zip.generate to create the .zip file data, and write it to file using fs. 使用zip.generate创建.zip文件数据,然后使用fs将其写入文件。

The resulting file can be downloaded or whatever you would like to do with it. 可以下载生成的文件,也可以进行任何操作。 I have seen no issues using this method. 使用此方法我没有发现任何问题。

If you want to zip more than one directory, just repeat steps 1 and 2 before you zip.generate, creating a new zip.folder for each directory. 如果要压缩多个目录,请在执行zip.generate之前重复步骤1和2,为每个目录创建一个新的zip.folder。

Just use只需使用

archive.on("finish",function(){
    res.download(__dirname + "/backups/" + zipFile);
  })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM