Reputation: 2081
I'd like to save files received from json object in a REST API app and here is the code:
router.post('/addphoto', checkAuth, (req, res)=> {
let filename = Math.floor(Math.random() * 100000);
let dir = './uploads/' + req.user.id;
//Not sure about this
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
base64String = req.body.file;
let base64Image = base64String.split(';base64,').pop();
let filePath = dir + "/" + filename
fs.writeFile( filePath, base64Image, {encoding: 'base64'}, function(err) {
console.log('File created');
});
...
It does the job but I've read that existsSync
is deprecated, and also I'm not sure if it's a good idea to use sync code inside a router which is async by nature.
So I'm wondering what is the idiomatic way to do so in such circumstances?
Upvotes: 4
Views: 21984
Reputation: 16594
From official docs https://nodejs.org/api/fs.html#fspromisesaccesspath-mode
fs.access will throw an error if file don't exist. So you will not have a boolean to check if file exist or not, like java does from ancient ages. You should use a try/catch:
var isDirExist = false;
try{
await fs.promises.access("/foo/bar");
isDirExist = true;
}catch(e){
isDirExist = false;
}
If this looks problematic, official docs says:
Using fsPromises.access() to check for the accessibility of a file before calling fsPromises.open() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file is not accessible.
Upvotes: 1
Reputation: 6538
Modern async/await way
const isDirExist = async path => await fs.promises.access(path).then(()=>true).catch(()=>false);
Using
const isDirExist = async path => await fs.promises.access(path).then(()=>true).catch(()=>false);
(async () => {
console.log(await isDirExist('/my/path/'));
})()
Upvotes: 1
Reputation: 3230
The below code will check if the destination exists. If it doesn't exist, it'll create the destination as a directory. It will also create the parent directories if they don't exist (because of recursive: true
). It does not use Sync functions and will not block requests if used in a web server.
const fs = require('fs');
const targetDirectory = 'your/path/here';
fs.mkdir(targetDirectory, { recursive: true }, (error) => {
if (!error) {
console.log('Directory successfully created, or it already exists.');
return;
}
switch (error.code) {
case 'EEXIST':
// Error:
// Requested location already exists, but it's not a directory.
break;
case 'ENOTDIR':
// Error:
// The parent hierarchy contains a file with the same name as the dir
// you're trying to create.
break;
default:
// Some other error like permission denied.
console.error(error);
break;
}
});
See: mkdir docs.
Upvotes: 0
Reputation: 614
If you use node-fs-extra you can utilize...
fs.ensureDir(dir[,options][,callback])
Which by definition...
Ensures that the directory exists. If the directory structure does not exist, it is created.
See also fs.ensureDirSync
Upvotes: 0
Reputation: 944568
I've read that existsSync is deprecated
It isn't. See the manual:
fs.exists() is deprecated, but fs.existsSync() is not. The callback parameter to fs.exists() accepts parameters that are inconsistent with other Node.js callbacks. fs.existsSync() does not use a callback.
I'm not sure if it's a good idea to use sync code inside a router which is async by nature.
There's nothing intrinsically wrong about doing something synchronous inside something that is asynchronous — most JS is synchronous — but it does mean that the feature would block the event loop while looking at the file system, and looking at the file system is a relatively time-consuming operation, so it wouldn't be good for performance.
Your code might not need that level of performance, but that's a judgement call we can't make for you.
exists
is right next to existsSync
in the manual and says:
Deprecated: Use fs.stat() or fs.access() instead.
So pick one of those.
access
has an example:
// Check if the file exists in the current directory. fs.access(file, fs.constants.F_OK, (err) => { console.log(`${file} ${err ? 'does not exist' : 'exists'}`); });
Upvotes: 6
Reputation: 1157
You can use access
fs.access(myDir, function(err) {
if (err && err.code === 'ENOENT') {
fs.mkdir(myDir); //Create dir in case not found
}
});
Upvotes: 8
Reputation: 1445
You can use existsSync
as it's not deprecated. it's exists
that got deprecated. I've attached a screenshot and link below so you can use it without any problem.
link->
https://nodejs.org/api/fs.html#fs_fs_existssync_path
image->
Upvotes: 4