2016-07-19 22 views
0

Ich muss Zip-Archiv in meiner Nodejs-Anwendung herunterladen und entpacken. Ich habe diesen Code:Zip-Datei kann nach dem Herunterladen durch die Anwendung nodejs wegen eines ungültigen CEN-Fehlers nicht geöffnet werden

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); 
      } 
     }); 

Dieser Code gibt mir Fehler:

Can not create zip, bad data Invalid CEN header (bad signature)

Ich verwende Windows 7. Ich kann nicht einmal diese ZIP-Datei öffnen, mit 7-Zip oder WinRAR (einfache Fehler wie beschädigte Daten).

Auch utils.apiRequest Funktion Körper ist:

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; 
} 

Wie kann ich mein Problem zu lösen?

PS: Ich habe keine Probleme mit curl :)

+0

Welche ist Ihr 'loadedData'? – vincent

+0

Es ist Zeichenfolge. Ich habe es in der apiRequest-Funktion von https Node-Modul bekommen. Ich werde den Code der Funktion in 1 Stunde hinzufügen. –

+0

Ich habe den Code der Funktion 'utils.apiRequest' hinzugefügt, damit Sie den Typ von 'loadedData' sehen können. –

Antwort

1

(als Antwort hinzufügen, damit ich den Code-Snippet veröffentlichen kann)

@vincent auf dem richtigen Weg ist denke ich - klinge wie Sie schreibe die Daten nicht als Binärdatei in die Datei. Es ist oft einfacher, nur Rohr eine Download-Anforderung direkt in eine Datei:

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); 
    } 
}) 

Ohne zu wissen, wo utils.apiRequest kommt aus ist es schwer zu sagen, ob dies für Sie praktikabel ist, aber hoffentlich hilft es.

+0

Ich werde den Code apiRequest in 1 Stunde hinzufügen. –

+0

Ich habe den Code der Funktion 'utils.apiRequest' hinzugefügt. –

+0

Eine Frage: Muss ich den Stream irgendwie manuell schließen? Nach der Verwendung Ihres Ansatzes hört meine Anwendung nicht auf. Es sieht so aus, als würde ich auf ein Unendlichkeits-Timeout warten. –

2

Das Problem ist, dass Sie die empfangenen Daten in einen UTF-8-String sind Decodierung:

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

Da eine Zip-Datei binär ist, sollten Sie einen Puffer verwenden. Hier

ist ein Beispiel Ersatz für Ihre utils.apiRequest mit Puffer:

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; 
} 
+0

Wie genau muss ich meinen Code schreiben? '.toString' ist redunant? Ich habe es versucht. Das funktioniert nicht. –

+0

dataBlock ist ein Puffer. Sie können also nicht '+ =' zum Anhängen verwenden. Der Knoten hat keine Append-Funktion für den Buffer, daher müssen Sie entweder selbst schreiben oder das Modul node-bufferjs verwenden. Sie können die geladenen Daten auch direkt mit Ihrer appendFileSync-Funktion schreiben oder sie an die Zieldatei leiten. – vincent

+0

Ah. Dies ist die Antwort für meine Frage http://stackoverflow.com/questions/38466944/can-not-open-zip-file-after-download-through-nodejs-application-because-of-in/38474661#comment64351596_38469236. 'loadedData' ist nur Puffer, wenn ich eine ZIP-Datei zum Download benötige? Ist diese einfache Zeichenfolge, wenn ich einfache API-Anfrage mache? Sollte ich meinen Code in anderen einfachen (nicht '.zip'-, nur JSON-Anfragen) Fällen ändern? –