I am just trying to upload and save images in my public/images folder, I am getting the details of file by req.files, after that I am getting this type of Error: EXDEV, rename 'c:\Users\abdul\AppData\Local\Temp\3348-qiy7kl.jpg'
here is my stuff
app.post('/upload',function(req,res){
var tmp_path = req.files.file.path;
var target_path = './public/images/' + req.files.file.originalFilename;
fs.rename(tmp_path, target_path, function(err) {
if (err) throw err;
fs.unlink(tmp_path, function() {
if (err) throw err;
res.send('File uploaded to: ' + target_path + ' - ' + req.files.file.size + ' bytes');
});
});
})
};
Can any body give any suggestion or give me any reference so that I can handle it?
Try this one
console.log("File Name " + req.files.file.name);
console.log("File Path " + req.files.file.path);
fs.readFile(req.files.file.path, function (err, data) {
var newPath = "public/images/" + req.files.file.originalFilename;
console.log(newPath);
/// write file to uploads/fullsize folder
fs.writeFile(newPath, data, function (err) {
/// let's see it
});
Related
How do we run seperate functions based on the users Operating System?
I have two functions for returning relative paths to given files by searching for them recursively within subdirectories of given working directory's.
I have one for Windows, see below..
WINDOWS variant
console.log("Locating File...");
exec('set-location ' + folder + ';' + ' gci -path ' + folder + ' -recurse -filter ' +
file + ' -file | resolve-path -relative', { 'shell':'powershell.exe' }, (error, stdout, stderr) => {
var filePath = stdout.substring(stdout.indexOf(".\\") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate the file...");
return;
}
And one for Linux & macOS, see below...
LINUX/OSX variant
console.log("Locating File...")
console.log();
exec('find -name "' + file + '"', { cwd: folder }, (error, stdout, stderr) => {
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate the file...");
return;
}
I want to execute these functions based on the users Operating System if that's possible?
I've had a look at the StackOverflow question..
How do I determine the current operating system with Node.js
which is how I found out how to detect the current user OS, as well as the StackOverflow Question..
python: use different function depending on os.
Aside from the 2nd issue referenced being for python, I am basically trying to achieve the same thing from the 2nd issue but with nodeJS, by using the solution from the 1st issue.
My latest attempt was the following below, but for some reason it doesn't return anything but a blank console.
const fs = require("fs");
const platform = require("process");
const path = require("path");
var exec = require("child_process").exec
var folder = "just/some/folder/location"
var file = "file.txt"
// Windows process
if (platform === "win32") {
console.log("Locating File...");
exec('set-location ' + folder + ';' + ' gci -path ' + folder + ' -recurse -filter ' +
file + ' -file | resolve-path -relative', { 'shell':'powershell.exe' }, (error, stdout, stderr) => {
// relative path output for Windows
var filePath = stdout.substring(stdout.indexOf(".\\") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate the file...");
return;
} else if (process.platform === "linux" + "darwin") {
// Linux & Unix process
console.log("Locating File...")
console.log();
exec('find -name "' + file + '"', { cwd: folder }, (error, stdout, stderr) => {
// relative path output for Linux & macOS
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
if (error !== null) {
console.log("Cannot Locate file... \n\n" + error);
return;
};
console.log("found file: " + filePath);
// Read the file and show it's output to confirm everything ran correctly.
fs.readFile(path.join(folder, file), (error, data) => {
if (error) {
console.log("error reading file \n\n" + error);
return;
}
});
});
};
});
};
Problem solved, after doing a bit of research, I was using if else else if statements & process.platform wrong...
First, when I was declaring process.platform I was using...
const platform = require("process");
when according to process.platform documentation for CJS it should be...
const { platform } = require("node:process");
Second, I was using if else else if statements wrong!
In my issue stated above I was using if else else if statements with process.platform like so..
} else if (process.platform === "linux" || "darwin") {
// Linux & macOS code to execute
}
which was completely wrong!
I should have been using if else else if statements with process.platform like so...
if (process.platform === "win32") {
// Windows code to be executed!
} else if (process.platform === "linux") {
// Linux Code to be executed!
} else {
process.platform === "darwin";
// macOS Code to be executed!
}
I've managed to produce the following code which works on Windows, Linux and macOS closest to the way I need it to.
Hopefully this helps anyone new to JS like me.
const fs = require("fs");
const { platform } = require("node:process");
const path = require("path");
var exec = require("child_process").exec
var folder = "just/some/folder/location"
var file = "file.txt"
// Windows Process
if (process.platform === "win32") {
// executes Powershell's "set-location" & "gci" commands...
//...to locate a given file recursively...
//...and returns its relative path from inside the given...
//...working directory's subdirectories.
exec('set-location "' + '"' + folder + '"'
+ ';' + ' gci -path ' + '"' + folder + '"'
+ ' -recurse -filter ' + '"' + file + '"' +
' -file | resolve-path -relative', (error, stderr, stdout) => {
// sets the relative file path from ".\this\way\to\the\file.txt",
// to "this\way\to\the\file.txt".
var filePath = stdout.substring(stdout.indexOf(".\\") + 2).trim("\n");
// throw an error if the file isnt found at all!
if (error !== null) {
console.log("Cannot locate the given file... \n" + error);
return;
};
// read the file after it's been found.
fs.readFile(path.join(folder, filePath), 'utf8', (error, data) => {
if (error) {
console.log("There was a problem reading the given file... \n" + error);
return;
};
// Then print the data from fs.readFile...
//...to confirm everthing ran correctly.
console.log(data);
});
});
} else if (process.platform === "linux") {
// executes findUtil's "find" command...
//...to locate a given file recursively...
//...and return its relative path from inside the given...
//...working directory's subdirectories.
exec('find -name "' + file + '"', { cwd: folder }, (error, stderr, stdout) => {
// sets the relative file path from "./this/way/to/the/file.txt",
// to "this/way/to/the/file.txt".
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
// throw an error if the file isnt found at all!
if (error !== null) {
console.log("Cannot locate the given file... \n" + error);
return;
};
// read the file after it's been found.
fs.readFile(path.join(folder, filePath), 'utf8', (error, data) => {
if (error) {
console.log("There was a problem reading the given file... \n" + error);
return;
};
// Then print the data from fs.readFile...
//...to confirm everthing ran correctly.
console.log(data);
});
});
} else {
// Uses APPLES built BSD findUtils 'find' command to locate the file inside the folder and subdirectories
exec('find ' + '"' + apkFolder + '"' + ' -name ' + '"' + file + '"', (error, stderr, stdout) => {
// sets the relative file path from "./this/way/to/the/file.txt",
// to "this/way/to/the/file.txt".
var filePath = stdout.substring(stdout.indexOf("./") + 2).trim("\n");
// throw an error if the file isnt found at all!
if (error !== null) {
console.log("Cannot locate the given file... \n" + error);
return;
};
// read the file after it's been found.
fs.readFile(path.join(folder, filePath), 'utf8', (error, data) => {
if (error) {
console.log("There was a problem reading the given file... \n" + error);
return;
};
// Then print the data from fs.readFile...
//...to confirm everthing ran correctly.
console.log(data);
});
});
}
A coach in my application can upload an image for his profile, clients, programs and exercise.
After the file has been upload, the nodejs server rename it. Then the nodejs server needs to insert / update the image name on the db, according to the form that sends the image (registration, edit user, add client, edit client and so on...).
Therefore I want to send additional data / parameters to the nodejs function.
HTML:
<form name="userUpdateForm" action="/university/uploadImage" method="post" enctype="multipart/form-data" id="editUserForm">
<label>Replace Logo Image</label></br>
<input id="uploadFile" name="filetoupload" type="file">
<input type="submit">
</form>
Node:
router.post('/uploadImage', function (req,res,next) {
var newpath = "";
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.filetoupload.path;
var time = new Date();
var newImageName = time.getHours() + "-" + time.getMinutes() + "-" + time.getSeconds() + "-" + files.filetoupload.name;
newpath = './uploaded/' + newImageName;
//sendToDbImageName(newImageName);
fs.readFile(oldpath, function (err, data) {
if (err) throw err;
console.log('File read!');
// Write the file
fs.writeFile(newpath, data, function (err) {
if (err) throw err;
console.log('File uploaded and moved!');
console.log('File written!');
res.redirect(url + '?uid=' + globalUid + '#/editUser');
});
// Delete the file
fs.unlink(oldpath, function (err) {
if (err) throw err;
console.log('File deleted!');
});
});
});
});
Update:
This is how I solved that:
One function that's takes an image from different forms (coach, client, program, exercise), generate unique file name, and insert / update the database.
Don't repeat; check,
Don't go twice to the server; check,
Prevent redirect after file was upload; check.
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, __dirname + '/../uploaded')
},
filename: function (req, file, cb) {
var time = new Date();
cb(null, time.getHours() + "-" + time.getMinutes() + "-" +
time.getSeconds() + "-" + file.originalname) //Appending extension
}
})
var upload = multer({ storage: storage });
router.post('/uploadImage', upload.single('avatar'), function (req, res, next) {
var formName = req.body.formName;
switch (formName) {
case "editUser":
var sql = "UPDATE coachdirectory SET logo = '" + req.file.filename + "' WHERE uid = '" + req.body.uid + "'";
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result.affectedRows + " record(s) updated");
});
res.redirect(url + '/?uid=' + req.body.uid + '#/yourClients');
break;
case "registerUser:
other business logic
break;
}
});
The best practice is using Multer package developed by ExpressJS. Server handling file upload is really difficult, so they created multer which is basically built on top of busboy. There are some edge cases you also need to handle when you do it by scratch. No need of reinventing the wheel. Better use Multer as you can pass normal formal data in multipart itself. Multer will attach those to req.body by default.
In Multer, you have the flexibility to rename the file before saving it the database itself or keep the original filename.
I have a root directory say "A" inside this directory i am having lots of directories say "1","2","3","4","5"........ and in all these subdirectories i have single file called cucumber.json. All i want to do is read the cucumber.json file and get the accumulated result. How can i achieve this using node js.
In the below screen shot my root directory is "cucumber" and inside that i have lot of sub directories. All these sub directories contains a single file named cucumber.json.
Are there any dedicated node package which can make my work easy.
Let me know if any further info is required.
Hi there please try the following (javascript):
// Require filesystem package for IO operations
var fs = require('fs');
// Put the path you are looking for here
var path = "d:\\nodef";
//Call the function defined below
recursiveloop(path, function(err,result){
/* begin processing of each result */
// For each file in the array
for(i=0;i<result.length;i++)
{
//Write the name of the file
console.log('Processing: ' + result[i]);
//Read the file
fs.readFile(result[i], 'utf8', function(err, data){
//If there is an error notify to the console
if(err) console.log('Error: ' + err);
//Parse the json object
var obj = JSON.parse(data);
//Print out contents
console.log('Name: ' + obj.name);
console.log('Position: ' + obj.position);
})
}
});
// Asynchronous function to read folders and files recursively
function recursiveloop(dir, done)
{
var results = [];
fs.readdir(dir, function(err, list){
if (err) return done(err);
var i = 0;
(function next() {
var file = list[i++];
if (!file) return done(null, results);
file = dir + '/' + file;
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
recursiveloop(file, function(err, res) {
results = results.concat(res);
next();
});
} else {
results.push(file);
next();
}
});
})();
});
}
I have a problem but I don't know how to solve it.
I reading a file from s3, then I save it to a folder(downloads). After that, I read the file that I saved in the folder (that I saved in downloads) and re-size it + save it in a different folder with a different name (resized).
Then, I want to read again this file in order to upload it again in its the new size but when I try to do that it throws an error that there is no such file in this directory but when I check it in my folder it dose.
My guess it's trying to read before the image is written in the new folder (resized)
How can I fix it?
update
so accroding to commits this is what I did but it disen't print out anything in fs.readFileAsync.
Why?
var image = new ImageResize(__dirname +'/../downloads/'+ hash + '.png');
image.smartResizeDown({
width: 200,
height: 200
}).then(function () {
image.stream(function (err, stdout, stderr) {
var writeStream = fs.createWriteStream(__dirname +'/../resized/'+ hash + 'resize.png');
stdout.pipe(writeStream);
}).then(function(){
fs.readFileAsync('C:/Users/user/Desktop/cloud/new/resized/'+hash+'resize.png', function(error, buf){
if(error)
console.log(error);
else
console.log('yay');
});
});
});
var image = new ImageResize(__dirname +'/../downloads/'+ hash + '.png');
image.smartResizeDown({
width: 200,
height: 200
})
.then(function () {
return new Promise(function(resolve, reject) {
image.stream(function (err, stdout, stderr) {
var writeStream = fs.createWriteStream(__dirname +'/../resized/'+ hash + 'resize.png');
stdout.pipe(writeStream);
resolve();
})
});
})
.then(function(){
fs.readFileAsync('C:/Users/user/Desktop/cloud/new/resized/'+hash+'resize.png', function(error, buf) {
if(error)
console.log(error);
else
console.log('yay');
});
return null;
});
Assuming bluebird object is in Promise named variable.
Trying to allow users to upload image files to the Node.js server in a MEAN Stack application. I am using ng-file-upload for the client side angular directive. That seems to be working good enough. I run into an error when I pass the image to the server.
I use an API route to handle the work on the server side. The server will be responsible for saving the file to disk with node-multiparty module. It seems to hit route but when it tries to emit a close event I get the error. throw new Error('"name" and "value" are required for setHeader().'
The file I want is in my temp folder but it doesn't get saved to the target directory on my server plus I get the header error after the file should have been saved. So I need to stop the error and save the file with fs.rename() to the target image directory.
Here is the code that is breaking.
file api.js
// router to save images
router.route('/img/upload')
.post(function (req, res) {
console.log("image upload hits the router")
var options = {};
var count = 0;
var form = new multiparty.Form(options);
//save file to disk
form.on('file', function (name, file) {
var uploadDirectory = 'img/user/profile/';
var oldPath = file.path;
var newPath = uploadDirectory + file.originalFilename;
fs.rename(oldPath, newPath, function (err) {
if (err) throw err;
console.log('renamed complete');
});
});
// Close emitted after form parsed
form.on('close', function () {
console.log('Upload completed!');
res.setHeader('text/plain'); // Here is the line that gives an error.
res.end('Received ' + count + ' files');
});
// Parse req
form.parse(req);
});
So this is what I got to work for me
The actual line that gave me an error was setHeaders. It appears I needed to put the name and value as strings separated by a comma. This works perfectly for me now. I hope it saves everyone time coding.
// post
.post(function (req, res) {
var options = {};
var count = 0;
var form = new multiparty.Form(options);
form.on('error', function (err) {
console.log('Error parsing form: ' + err.stack);
});
//save file to disk
form.on('file', function (name, file) {
var uploadDirectory = '/img/user/profile/';
var oldPath = file.path;
var newPath = uploadDirectory + file.originalFilename;
fs.rename(oldPath, newPath, function (err) {
if (err) throw err;
console.log('renamed complete');
});
});
// Close emitted after form parsed
form.on('close', function () {
console.log('Upload completed!');
res.setHeader('Content-Type', 'text/plain');
res.end('Received ' + count + ' files');
});
// Parse req
form.parse(req);
});