3

我需要在我的 nodejs 应用程序中下载并解压缩 zip 存档。我有这个代码:

utils.apiRequest(teamcityOptions)
        .then(function (loadedData) {
          var tempDir = tmp.dirSync();
          var tmpZipFileName = tempDir.name + "\\" + 'bob.zip';

          fs.appendFileSync(tmpZipFileName, loadedData);

          var zip;
          try {
            zip = new AdmZip(tmpZipFileName);
          } catch (e) {
            log('Can not create zip, bad data', e);
          }
        });

这段代码给了我错误:

无法创建 zip,错误数据 CEN 标头无效(签名错误)

我使用的是 Windows 7。我什至无法使用 7-zip 或 WinRAR 打开这个 ZIP 文件(简单的错误,如损坏的数据)。

此外,utils.apiRequest函数体是:

utils.apiRequest: function (options) {
  var deferred = defer();
  https.get(options, function (request) {
    var loadedData = '';
    request.on('data', function (dataBlock) {
      loadedData += dataBlock.toString('utf8');
    });
    request.on('end', function () {
      deferred.resolve(loadedData);
    })
  });
  return deferred.promise;
}

我该如何解决我的问题?

PS:我使用没有问题curl:)

4

2 回答 2

3

问题是您正在将接收到的数据解码为 utf8 字符串:

request.on('data', function (dataBlock) {
  loadedData += dataBlock.toString('utf8'); // this is wrong
});

由于 zip 文件是二进制文件,因此您应该使用 Buffer。

utils.apiRequest下面是一个用 Buffer替换你的示例:

utils.apiRequest: function (options) {
    var deferred = defer();
    https.get(options, function (request) {
        var data = []; 
        request.on('data', function (dataBlock) {
            data.push(dataBlock); 
        });
        request.on('end', function () {
            deferred.resolve(Buffer.concat(data));
        });
    });
    return deferred.promise;
}
于 2016-07-20T07:14:36.673 回答
2

(添加为答案,以便我可以发布代码片段)

我认为@vincent 走在正确的轨道上-听起来您没有将数据作为二进制文件写入文件。将下载请求直接通过管道传输到文件通常更容易:

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

var tmpZipStream = fs.createWriteStream('bob.zip');
var request = http.get('http://example.com/example.zip', function(response) {
  response.pipe(tmpZipStream);
});

tmpZipStream.on('close', function() {
  var zip;
  try {
    zip = new AdmZip('bob.zip');
  } catch (e) {
    console.log('Can not create zip, bad data', e);
  }
})

在不知道 utils.apiRequest 的来源的情况下,很难说这对您是否可行,但希望它有所帮助。

于 2016-07-19T21:59:30.143 回答