Ich mache mit node.js rum und habe zwei Möglichkeiten entdeckt, eine Datei zu lesen und über das Kabel zu senden, sobald ich festgestellt habe, dass sie existiert, und den richtigen MIME-Typ mit writeHead gesendet habe:
// read the entire file into memory and then spit it out
fs.readFile(filename, function(err, data){
if (err) throw err;
response.write(data, 'utf8');
response.end();
});
// read and pass the file as a stream of chunks
fs.createReadStream(filename, {
'flags': 'r',
'encoding': 'binary',
'mode': 0666,
'bufferSize': 4 * 1024
}).addListener( "data", function(chunk) {
response.write(chunk, 'binary');
}).addListener( "close",function() {
response.end();
});
Bin ich zu Recht davon ausgegangen, dass fs.createReadStream eine bessere Benutzererfahrung bietet, wenn die betreffende Datei etwas Großes wie ein Video ist? Es fühlt sich an, als wäre es weniger blockartig; Ist das wahr? Gibt es andere Vor-, Nachteile, Vorbehalte oder Fallstricke, die ich wissen muss?
quelle
bufferSize
Option wurde zugunsten von abgelehnthighWaterMark
.fs.readFile
lädt die gesamte Datei in den Speicher, wie Sie bereits erwähnt haben, währendfs.createReadStream
die Datei in Blöcken der von Ihnen angegebenen Größe gelesen wird.Der Client empfängt Daten auch schneller,
fs.createReadStream
wenn sie beimfs.readFile
Lesen in Blöcken gesendet werden, während die gesamte Datei ausgelesen wird und erst dann an den Client gesendet wird . Dies kann vernachlässigbar sein, kann jedoch einen Unterschied machen, wenn die Datei sehr groß und die Festplatten langsam sind.Denken Sie jedoch daran, wenn Sie diese beiden Funktionen in einer 100-MB-Datei ausführen, verwendet die erste 100 MB Speicher zum Laden der Datei, während die letztere höchstens 4 KB verwendet.
Bearbeiten: Ich sehe wirklich keinen Grund, warum Sie
fs.readFile
besonders verwenden würden, da Sie sagten, dass Sie große Dateien öffnen werden.quelle
fs.readFile
wir den Fortschritt pro Beispiel nicht erfassen?Wenn es sich um eine große Datei handelt, wird "readFile" den Speicher belasten, da der gesamte Dateiinhalt im Speicher gepuffert wird und Ihr System möglicherweise hängen bleibt. Während ReadStream Chunks einliest.
Führen Sie diesen Code aus und beobachten Sie die Speichernutzung auf der Registerkarte Leistung des Task-Managers.
var fs = require('fs'); const file = fs.createWriteStream('./big_file'); for(let i=0; i<= 1000000000; i++) { file.write('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n'); } file.end(); //.............. fs.readFile('./big_file', (err, data) => { if (err) throw err; console.log("done !!"); });
Tatsächlich sehen Sie nicht "erledigt !!" Botschaft. "readFile" kann den Dateiinhalt nicht lesen, da der Puffer nicht groß genug ist, um den Dateiinhalt aufzunehmen.
Verwenden Sie jetzt anstelle von "readFile" readStream und überwachen Sie die Speichernutzung.
Hinweis: Der Code stammt aus dem Samer Buna Node-Kurs auf Pluralsight
quelle
Ein anderes, vielleicht nicht so bekannt , was, ist , dass ich glaube , dass Knoten ist besser bei Reinigung nicht verwendete Speicher nach der Verwendung im
fs.readFile
Vergleich zufs.createReadStream
. Sie sollten dies testen, um zu überprüfen, was am besten funktioniert. Ich weiß auch, dass dies mit jeder neuen Version von Node besser geworden ist (dh der Garbage Collector ist mit solchen Situationen schlauer geworden).quelle