当前位置: 首页 > 面试题库 >

如何在NodeJs的内存中下载和解压缩zip文件?

秦涵映
2023-03-14
问题内容

我想从互联网上下载一个zip文件,然后将其解压缩到内存中而不保存到临时文件中。我怎样才能做到这一点?

这是我尝试过的:

var url = 'http://bdn-ak.bloomberg.com/precanned/Comdty_Calendar_Spread_Option_20120428.txt.zip';

var request = require('request'), fs = require('fs'), zlib = require('zlib');

  request.get(url, function(err, res, file) {
     if(err) throw err;
     zlib.unzip(file, function(err, txt) {
        if(err) throw err;
        console.log(txt.toString()); //outputs nothing
     });
  });

[编辑]就像我建议的那样,我尝试使用adm-zip库,但仍然无法完成这项工作:

var ZipEntry = require('adm-zip/zipEntry');
request.get(url, function(err, res, zipFile) {
        if(err) throw err;
        var zip = new ZipEntry();
        zip.setCompressedData(new Buffer(zipFile.toString('utf-8')));
        var text = zip.getData();
        console.log(text.toString()); // fails
    });

问题答案:

您需要一个可以处理缓冲区的库。最新版本adm-zip将:

npm install adm-zip

我的解决方案使用该http.get方法,因为它返回Buffer块。

码:

var file_url = 'http://notepad-plus-plus.org/repository/7.x/7.6/npp.7.6.bin.x64.zip';

var AdmZip = require('adm-zip');
var http = require('http');

http.get(file_url, function(res) {
  var data = [], dataLen = 0;

  res.on('data', function(chunk) {
    data.push(chunk);
    dataLen += chunk.length;

  }).on('end', function() {
    var buf = Buffer.alloc(dataLen);

    for (var i = 0, len = data.length, pos = 0; i < len; i++) { 
      data[i].copy(buf, pos); 
      pos += data[i].length; 
    }

    var zip = new AdmZip(buf);
    var zipEntries = zip.getEntries();
    console.log(zipEntries.length)

    for (var i = 0; i < zipEntries.length; i++) {
      if (zipEntries[i].entryName.match(/readme/))
        console.log(zip.readAsText(zipEntries[i]));
    }
  });
});

这个想法是创建一个缓冲区数组,并在最后将它们连接成一个新的缓冲区。这是因为无法调整缓冲区大小。

更新资料

这是一个更简单的解决方案,它request通过encoding: null在选项中进行设置,使用模块在缓冲区中获取响应。它还遵循重定向并自动解析http / https。

var file_url = 'https://github.com/mihaifm/linq/releases/download/3.1.1/linq.js-3.1.1.zip';

var AdmZip = require('adm-zip');
var request = require('request');

request.get({url: file_url, encoding: null}, (err, res, body) => {
  var zip = new AdmZip(body);
  var zipEntries = zip.getEntries();
  console.log(zipEntries.length);

  zipEntries.forEach((entry) => {
    if (entry.entryName.match(/readme/i))
      console.log(zip.readAsText(entry));
  });
});

body响应的是,可以直接传递到缓冲器AdmZip,简化了整个过程。



 类似资料:
  • 问题内容: 我想使用urllib下载文件,并在保存之前对文件进行解压缩。 这就是我现在所拥有的: 最终将写入空文件。我该如何实现自己的追求? 更新的答案: 问题答案: 在写完之后,但要传递给之前,您需要寻找到开始的地方。否则它将被模块从头读取,并显示为空文件。见下文:

  • 问题内容: 我正在下载包含XML的压缩文件,由于延迟要求,我希望避免在操作之前将zip文件写入磁盘。但是,这不足以满足我的需求。没有办法说“这是一个zip文件的字节数组,请使用它”而不将其转换为流,并且它不可靠,因为它会扫描条目标头(请参阅EDIT下面的讨论,以了解为什么它不可靠)。 我尚无法访问要处理的zip文件,因此我不知道我是否能够通过来处理它们,因此我需要找到一种适用于任何有效ZIP文件的

  • 问题内容: 如何从命令外壳中获得与.zip文件(而不是gzip)的等价形式,而无需将其解压缩?也就是说,如何列出.zip压缩文件中压缩的不同文件? 问题答案: Perreal的答案是正确的,但我建议安装工具(在发行版的软件包管理器中查找)。然后,对于任何类型的存档文件,bzip2,gzip,tar …,您只需记住一个命令:

  • 问题内容: 我设法使我的第一个python脚本起作用,该脚本从URL下载.ZIP文件的列表,然后继续提取ZIP文件并将其写入磁盘。 我现在无所适从,无法实现下一步。 我的主要目标是下载并提取zip文件,并通过TCP流传递内容(CSV数据)。如果可以的话,我宁愿不实际将任何zip或解压缩的文件写入磁盘。 这是我当前的脚本,可以运行,但是不幸的是必须将文件写入磁盘。 问题答案: 我的建议是使用一个对象

  • 我有多个zip文件在一个文件夹和另一个zip文件存在于每一个这些zip文件夹。我想解压第一个和第二个zip文件夹,并创建它们自己的目录。 这是结构 如上所示,在中,我们有多个zip文件,在每个zip文件中,都存在另一个zip文件。我想解压缩,,和到新的文件夹中。我想使用与父zip文件夹相同的名称来放置每个结果。我尝试了以下答案,但这只解压缩第一个文件夹。 顺便说一句,我在Jenkins管道中运行这