I already have read the documentation of Node.js and, unless if I missed something, it does not tell what the parameters contain in certain operations, in particular fs.mkdir()
. As you can see in the documentation, it's not very much.
Currently, I have this code, which tries to create a folder or use an existing one instead:
fs.mkdir(path,function(e){
if(!e || (e && e.code === 'EEXIST')){
//do something with contents
} else {
//debug
console.log(e);
}
});
But I wonder is this the right way to do it? Is checking for the code EEXIST
the right way to know that the folder already exists? I know I can do fs.stat()
before making the directory, but that would already be two hits to the filesystem.
Secondly, is there a complete or at least a more detailed documentation of Node.js that contains details as to what error objects contain, what parameters signify etc.
Good way to do this is to use mkdirp module.
$ npm install mkdirp
Then use it to run function that requires the directory. Callback is called after path is created (if it didn't already exists). Error is set if mkdirp failed to create directory path.
var mkdirp = require('mkdirp');
mkdirp('/tmp/some/path/foo', function(err) {
// path was created unless there was error
});
Using a try {} catch {}
, you can achieve this very gracefully without encountering a race condition:
var mkdirSync = function (path) {
try {
fs.mkdirSync(path);
} catch(e) {
if ( e.code != 'EEXIST' ) throw e;
}
}
In both versions of the function, Node will try to create the directory and will throw an exception if it encounters an exception doing so. In the catch {}
clause however, we continue the script's execution as if nothing happened if the error code is EEXIST
, which means that the directory exist. If the error code isn't EEXIST
though, we ought to throw an error, because we're probably dealing with a filesystem exception such as EACCES
(permission denied).
Let's create the directories ./first/second/third
and ./first/second/fourth
, given:
var fs = require('fs')
, path = require('path');
var mkdirSync = function (path) {
try {
fs.mkdirSync(path);
} catch(e) {
if ( e.code != 'EEXIST' ) throw e;
}
}
mkdirSync( path.join('first') );
mkdirSync( path.join('first', 'second') );
mkdirSync( path.join('first', 'second', 'third') );
mkdirSync( path.join('first', 'second') ); // Just to demonstrate fault tolerance
mkdirSync( path.join('first', 'second', 'fourth') );
mkdir -p
-like recursionvar mkdirpSync = function (dirpath) {
var parts = dirpath.split(path.sep);
for( var i = 1; i <= parts.length; i++ ) {
fs.mkdirSync( path.join.apply(null, parts.slice(0, i)) );
}
}
mkdirpSync('first/second/third');
mkdirpSync('first/second/fourth');
The node.js docs for fs.mkdir
basically defer to the Linux man page for mkdir(2)
. That indicates that EEXIST
will also be indicated if the path exists but isn't a directory which creates an awkward corner case if you go this route.
You may be better off calling fs.stat
which will tell you whether the path exists and if it's a directory in a single call. For (what I'm assuming is) the normal case where the directory already exists, it's only a single filesystem hit.
These fs
module methods are thin wrappers around the native C APIs so you've got to check the man pages referenced in the node.js docs for the details.
You can use this:
if(!fs.existsSync("directory")){
fs.mkdirSync("directory", 0766, function(err){
if(err){
console.log(err);
response.send("ERROR! Can't make the directory! \n"); // echo the result back
}
});
}
You'd better not to count the filesystem hits while you code in Javascript, in my opinion.
However, (1) stat
& mkdir
and (2) mkdir
and check(or discard) the error code, both ways are right ways to do what you want.
Thanks.