2017-07-04 3 views
1

Der folgende Server-Code funktioniert gut für 5-GB-Datei mit wget http://localhost:11146/base/bigFile.zip, aber nicht mit Client-Seitencode.Wie kann man große Dateien in NodeJS herunterladen?

Server-Seitencode.

var http = require("http"); 
var fs = require("fs"); 
var filename = "base/bigFile.zip"; 

var serv = http.createServer(function (req, res) { 
    var stat = fs.statSync(filename); 
    res.writeHeader(200, {"Content-Length": stat.size}); 
    var fReadStream = fs.createReadStream(filename); 
    fReadStream.on('data', function (chunk) { 
     if(!res.write(chunk)){ 
      fReadStream.pause(); 
     } 
    }); 
    fReadStream.on('end', function() { 
     res.end(); 
    }); 
    res.on("drain", function() { 
     fReadStream.resume(); 
    }); 
}); 

serv.listen(1114); 

Client-Seite Code anfordern Modul. Was ist falsch in diesem Code?

var request = require('request') 
request('http:/localhost:11146/base/bigFile.zip', function (error, response, body) { 
    console.log('error:', error); // Print the error if one occurred 
    console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received 
    console.log('body:', body); // Print the HTML for the Google homepage. 
}); 

Fehler für Code über Client-Seite ist unter -

error: Error: Invalid protocol 
    at Request.init (/Users/air/Projects/node_modules/request/request.js:338:51) 
    at new Request (/Users/air/Projects//node_modules/request/request.js:105:8) 
    at request (/Users/air/Projects/Vertico/Vertico-CLI/node_modules/request/index.js:53:11) 
    at Object.<anonymous> (/Users/air/Projects/req.js:2:1) 
    at Module._compile (module.js:569:30) 
    at Object.Module._extensions..js (module.js:580:10) 
    at Module.load (module.js:503:32) 
    at tryModuleLoad (module.js:466:12) 
    at Function.Module._load (module.js:458:3) 
    at Function.Module.runMain (module.js:605:10) 
statusCode: undefined 
body: undefined 

I Client-Seite überarbeitet wget Shell-Prozess zu verwenden, anstelle von Anforderungspaket, das folgende Code ist, Das Problem ist - ich kann keinen guten Download-Fortschritt von wget sehen, keine Arbeit für diesen Code, so dass ich die Fortschrittsanzeige im Child-Prozess sehen kann.

const fs = require('fs'); 
    const child_process = require('child_process'); 

    var workerProcess = child_process.spawn('wget', ['-O','fdsf.zip', 'http://localhost:11146/base/bigFile.zip']); 

    workerProcess.stdout.on('data', function (data) { 
    console.log('stdout: ' + data); 
    }); 

    workerProcess.stderr.on('data', function (data) { 
    //console.log('stderr: ' + data); 
    }); 

    workerProcess.on('close', function (code) { 
     console.log('Download Completed' + code); 
    }); 

So schließlich möchte ich wissen, wie Sie eine Datei mit Client-seitigen Code in NodeJS geschrieben herunterladen?

Antwort

7

Der einfachste Weg ist request Modul

Hier können Sie versuchen, zu speichern gesamtes Ergebnis in Speicher zu verwenden und es Konsole anmelden. 5GB ist ziemlich groß, entweder müssen Sie Node.js Speicherlimit erhöhen (nicht empfohlen) oder Sie müssen Streams verwenden. Siehe die streaming example unten aus request npm Dokumentation:

const fs = require('fs'); 
const request = require('request'); 
request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) 

Sie müssen die Antwort Rohr, so dass, ob 1 MB oder 1 GB oder 1 TB ist, nur ein Bruchteil der Datei im Speicher sein wird, und es wird auf der Platte geschrieben werden als schnellstmöglich. Sie können den gleichen Ansatz mit den integrierten Funktionen von Node.js verwenden, aber die Implementierung wird schwierig sein und das Rad neu erfinden, wenn das Modul request vorhanden ist.

Für Download mit Fortschritt Sie request-progress Modul zusammen mit request Modul verwenden können, finden Sie im folgenden Beispiel (taken from their documentation):

var fs = require('fs'); 
var request = require('request'); 
var progress = require('request-progress'); 

// The options argument is optional so you can omit it 
progress(request('https://az412801.vo.msecnd.net/vhd/VMBuild_20141027/VirtualBox/IE11/Windows/IE11.Win8.1.For.Windows.VirtualBox.zip'), { 
    // throttle: 2000,     // Throttle the progress event to 2000ms, defaults to 1000ms 
    // delay: 1000,      // Only start to emit after 1000ms delay, defaults to 0ms 
    // lengthHeader: 'x-transfer-length' // Length header to use, defaults to content-length 
}) 
.on('progress', function (state) { 
    // The state is an object that looks like this: 
    // { 
    //  percent: 0.5,    // Overall percent (between 0 to 1) 
    //  speed: 554732,    // The download speed in bytes/sec 
    //  size: { 
    //   total: 90044871,  // The total payload size in bytes 
    //   transferred: 27610959 // The transferred payload size in bytes 
    //  }, 
    //  time: { 
    //   elapsed: 36.235,  // The total elapsed seconds since the start (3 decimals) 
    //   remaining: 81.403  // The remaining seconds to finish (3 decimals) 
    //  } 
    // } 
    console.log('progress', state); 
}) 
.on('error', function (err) { 
    // Do something with err 
}) 
.on('end', function() { 
    // Do something after request finishes 
}) 
.pipe(fs.createWriteStream('IE11.Win8.1.For.Windows.VirtualBox.zip')); 
+1

danke. irgendwelche Hinweise, wie man den Fortschritt festhält? – irobo

+2

Ich denke, Sie müssen zwischen dem Schreiben in die Datei tippen und einige Berechnungen mit der Inhaltslänge von Antwortheadern und den Bytes, die während jedes Ereignisses empfangen werden, machen. Es könnte Module geben, wenn ich auf eins stoße, werde Sie wissen lassen –

+2

@ user2979152 Siehe diese Frage: https: // stackoverflow.com/questions/18323152/get-download-progress-in-node-js-mit-anfrage zum herunterladen mit fortschritte –

2
var request = require('request') 
request('http:/localhost:11146/base/bigFile.zip', function (error, response, body) { 
    console.log('error:', error); // Print the error if one occurred 
    console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received 
    console.log('body:', body); // Print the HTML for the Google homepage. 
}); 

Es http://localhost:11146/base/bigFile.zip statt http:/localhost:11146/base/bigFile.zip sein sollten

1

Mein Version des Codes.

var fs = require('fs'); 
var request = require('request'); 
var progress = require('request-progress'); 
var url = 'http://localhost:4181'; 
var filename = 's.zip'; 
var pre = '----'; 

downloadManager = function(url,filename){ 
    progress(request(url), { 
    throttle:500 
    }) .on('progress', function (state) { 
     process.stdout.write(pre+''+ (Math.round(state.percent*100))+"%"); 
    }) 
    .on('error', function (err) { 
     console.log('error :('+err); 
    }) 
    .on('end', function() { 
     console.log(pre+'100% \n Download Completed'); 
    }) 
    .pipe(fs.createWriteStream(filename)); 
}; 


downloadManager(url,filename); 
+0

ganz einfachen code. – irobo

Verwandte Themen