I wish to read a file from a url and create a download stream with a different file name using nodejs on lambda.
Currently I am trying but failing with this code.
var fs= require('fs');
var url="https://upload.wikimedia.org/wikipedia/commons/5/51/Google.png";
fs.rename(url, "download.png", function(err) {
if ( err ) console.log('ERROR: ' + err);
});
fs.rename should be used for renaming the local file.
In your case, you would like to download a file from external URL and save it to new name, you can try this solution instead
var http = require('http');
var fs = require('fs');
var file = fs.createWriteStream("download.png");
var request = http.get("https://upload.wikimedia.org/wikipedia/commons/5/51/Google.png", function(response) {
response.pipe(file);
});
Related
I made a test with below node.js code in Node.js command and VS2015.
var fs = require('fs');
var http = require('http');
var url = require('url');
var ROOT_DIR = "Scripts/http/";
http.createServer(function (req, res) {
var urlObj = url.parse(req.url, true, false);
var reqPath = ROOT_DIR + urlObj.pathname;
fs.readFile(ROOT_DIR + urlObj.pathname, function (err, data) {
console.log(req.pathname);
if (err) {
res.writeHead(404);
res.end(JSON.stringify(err));
return;
}
res.writeHead(200);
res.end(data);
});
}).listen(1111);
console.log('http server is open');
If I run this from VS2015, and then I enter "http://localhost:1111/hello.html", it output the content in hello.html.
But if I open run below command, it tells me 'http server is open', but if I enter above url, it tells me file not found.
C:\Users\xx>cd E:\xx\NodeJs
C:\Users\xx>node E:\xx\NodeJsProject\Scripts\http\http_server_static.js
I assume it is relative path issue, but I do not know details about it.
Thanks for your help.
Making my comment into an answer so you can wrap up this question...
I'd suggest you probably have a problem with the relative path where the module directory is different in your two environments. Change it to an absolute path and it should perform the same in both places. You can call path.resolve() on your relative path and see what it comes out to be in both cases. Probably different.
How to save a CSV file directly to a folder destination?
Currently my code prompts the save window in the browser, I DO NOT want that.
I want NodeJS to save the CSV directly to a folder destination
How can I do that?
var fs = require('fs');
var express = require('express');
csv = require('express-csv');
var request = require('request');
var cheerio = require('cheerio');
var async = require('async');
var app = express();
app.get('/scraper', function(req, res){
var offset = req.query.offset || 0;
var limit = req.query.limit || 50;
if(gCounter === 0){
getStreamerInfo(offset, limit, function(response){
console.log("FILE READY!");
res.csv(response); // this export to browser but I want to save directly to a folder
});
}
});
Jus in case someone is looking for the same answer, this is what I did:
var fs = require('fs');
var jsonexport = require('jsonexport');
jsonexport(response,function(err, csv){
fs.writeFile("C:/outcome/c.csv", csv, function(err) {
if(err) {}
});
});
//res.csv(response);
I have a file in D: Drive of my local system. I need to download the file into the E: Drive. How to do this using node.js and http request? I am a beginner in node.js. Please give me valuable suggestions.
Note: The file may be in any type.
Here is an example:
// upload.js
var fs = require('fs')
var newPath = "E:\\newPath";
var oldPath = "D:\\oldPath";
exports.uploadFile = function (req, res) {
fs.readFile(oldPath, function(err, data) {
fs.writeFile(newPath, data, function(err) {
fs.unlink(oldPath, function(){
if(err) throw err;
res.send("File uploaded to: " + newPath);
});
});
});
};
// app.js
var express = require('express'), // fetch express js library
upload = require('./upload'); // fetch upload.js you have just written
var app = express();
app.get('/upload', upload.uploadFile);
app.listen(3000);
Basically there are two parts, one doing the copying from one drive to another, and the other one is for triggering. Once you run you app.js and make a GET request to localhost:3000/upload it will copy the file from newPath to the oldPath. For further information have a look to expressjs and fs.
Assuming it's a text file, you would have to write two node.js server.
The first would answer (all/specific, your choice) http get with the content of the file, the other would make a get and download the file.
server.js: Will work only for text file
var http = require('http'),
fs = require('fs'),
server = http.createServer(function (req, res){
res.writeHead(200, {'content-type': 'text/text'});
fs.readFile('E:/path/to/file.txt', function (data) {
res.write('' + data);
res.end();
});
}).listen(8080);
client.js
var http = require('http'),
fs = require('fs'),
file = fs.createWriteStream('D:/path/to/new.txt', {flags: 'w'});
http.get('http://localhost:8080', function (res) {
res.pipe(file, {end: 'false'});
res.on('end', function() {
file.end();
});
});
EDIT:
The only advantage versus anvarik's solution is that I don t use express...
I need to stream files from a client (nodejs command line) and a server (express nodejs).
This is the client side:
var request = require('request');
var fs = require('fs');
// ...
var readStream = fs.createReadStream(file.path);
readStream.on('end', function() {
that.emit('finished');
});
readStream.pipe(request.post(target));
// ...
This is the server side:
var fs = require('fs');
var path = require('path');
// ...
app.post('/:filename', function(req, res) {
req.setEncoding('binary');
var filename = path.basename(req.params.filename);
filename = path.resolve(destinationDir, filename);
var dst = fs.createWriteStream(filename);
req.pipe(dst);
req.on('end', function() {
res.send(200);
});
});
// ...
All is working, files are saved correctly on the server side... but they are about 50% bigger than the source files. I tried to see difference between the two files with hexdump and the server side file has similar content but with 0xC2 sometimes. I guess this is related to encoding.
Don't call req.setEncoding('binary').
This will convert every single chunk into strings and is mainly intended if you want to read strings from the stream. As you directly pipe the request to a file, you don't need to do it.
Let's say you create a zip file in-memory following the example from node-zip's documentation:
var zip = new require('node-zip')()
zip.file('test.file', 'hello there')
var data = zip.generate({type:'string'})
How do you then send data to a browser such that it will accept it as a download?
I tried this, but the download hangs at 150/150 bytes AND makes Chrome start eating 100% CPU:
res.setHeader('Content-type: application/zip')
res.setHeader('Content-disposition', 'attachment; filename=Zippy.zip');
res.send(data)
So what's the proper way to send zip data to a browser?
Using the archiver and string-stream packages:
var archiver = require('archiver')
var fs = require('fs')
var StringStream = require('string-stream')
http.createServer(function(request, response) {
var dl = archiver('zip')
dl.pipe(response)
dl.append(new fs.createReadStream('/path/to/some/file.txt'), {name:'YoDog/SubFolder/static.txt'})
dl.append(new StringStream("Ooh dynamic stuff!"), {name:'YoDog/dynamic.txt'})
dl.finalize(function (err) {
if (err) res.send(500)
})
}).listen(3000)
I recommend you to use streams for this approach.
var fs = require('fs');
var zlib = require('zlib');
var http = require('http');
http.createServer(function(request, response) {
response.writeHead(200, { 'Content-Type': 'application/octet-stream' });
var readStream = fs.createReadStream('test.file');
var unzipStream = zlib.createUnzip();
readStream.pipe(unzipStream.pipe(response));
}).listen(3000);
This will properly not work in real world (as I am not common with zlib) but it may give you the direction