2017-07-18 3 views
0

Ich habe eine Anforderung erhalten in Knoten, die erfolgreich Daten von API empfängt.Node-Anforderung in Datei schreiben beschädigt

Wenn ich diese Antwort direkt an eine Datei wie diese leitet, funktioniert es, die erstellte Datei ist eine gültige, lesbare PDF (wie ich von der API erwarten).

var http = require('request'); 
var fs = require('fs'); 

http.get(
{ 
    url:'', 
    headers:{} 
}) 
.pipe(fs.createWriteStream('./report.pdf')); 

Einfach, aber die Datei beschädigt wird, wenn ich die Ereignis Emittern der Anfrage verwenden wie dieses

http.get(
{ 
    url:'', 
    headers:{} 
}) 
.on('error', function (err) { 
    console.log(err); 
}) 
.on('data', function(data) { 
    file += data; 
}) 
.on('end', function() { 
    var stream = fs.createWriteStream('./report.pdf'); 
    stream.write(file, function() { 
     stream.end(); 
    }); 
}); 

Ich habe versucht, alle Arten diese Datei zu schreiben, und es endet immer in einer völlig leeren pdf - Die einzige gültige PDF-Datei ist die Pipe-Methode.

Wenn ich die Ereignisse protokollieren, scheint die Sequenz korrekt zu sein - dh, alle Teile empfangen und dann wird die end am Ende ausgelöst.

Es macht Dinge unmöglich, etwas nach dem Rohr zu tun. Was macht Pipe anders als der Writestream?

Antwort

4

Ich gehe davon aus, dass Sie file als String initialisieren:

var file = ''; 

Dann in Ihrem data-Handler, den neuen Teil der Daten, um es hinzuzufügen:

file += data; 

Dies führt jedoch ein IM explizite Konvertierung in (UTF-8-codierte) Strings. Wenn die Daten wie bei einer PDF-Datei tatsächlich binär sind, werden die Ausgabedaten ungültig.

Stattdessen möchten Sie die data Stücke zu sammeln, die Buffer Instanzen sind, und verwenden Sie Buffer.concat() all diese Puffer in eine große (binär) Puffer verketten:

var file = []; 
... 
.on('data', function(data) { 
    file.push(data); 
}) 
.on('end', function() { 
    file = Buffer.concat(file); 
    ... 
}); 
+0

tun u denken die Art, wie ich es tat, mit Strings ist ein Problem, auch wenn die Antwort tatsächlich utf8 ist? – yoyoma

+1

@yoyoma PDFs können binäre Daten enthalten, sie sind nicht vollständig zu 100% UTF-8-kodiert (der _text_ in den PDFs kann sein, aber es gibt viele andere Dinge in einem PDF). – robertklep

+0

thx eine Menge das ist das, das so funktionierte es richtig markiert - ich hatte verschiedene Puffer vorher versucht, aber ich denke nicht, dass ich die concat richtig gemacht habe – yoyoma

1

Wenn Sie nach dem Schreiben der Datei etwas tun möchten, können Sie einen Ereignis-Listener für finish für das von pipe zurückgegebene Objekt hinzufügen.

.pipe(fs.createWriteStream('./report.pdf')) 
.on('finish', function done() { /* the file has been written */ }); 

Quelle: https://nodejs.org/api/stream.html#stream_event_finish

Verwandte Themen