如何使用Node Js,Archiver和Express

时间:2016-04-15 01:36:41

标签: javascript node.js express zip node-archiver

我正在尝试压缩两个目录的内容并下载生成的.zip文件。一个目录包含.txt文件,另一个目录包含.jpg。我正在使用archiver来压缩文件并在节点js上运行express框架。我倾向于认为下载步骤中存在问题,因为在项目根目录中创建的结果压缩文件会按预期扩展,但是当下载文件时,我得到一个"错误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是一个全局变量。

关闭&#39;关闭&#39;正确启动日志并且不会发生错误,但下载后文件将无法打开。是否存在响应标头或我不知道的其他问题?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我使用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将其写入文件。
  4. 可以下载生成的文件或任何您想要使用它的文件。我发现使用这种方法没有问题。

    如果你想压缩多个目录,只需在zip.generate之前重复步骤1和2,为每个目录创建一个新的zip.folder。