Note: By the time this post is written, the Node.js is on version 0.6.10. Therefore anything in this post may or may not valid in the newer versions.
Node.js file system API provide a bunch of functions to read/write files. One of them is the fs.mkdir(path, [mode], [callback]). However, this function itself does not provide any option for you to create a directory if the parents folder is missing, it’ll trigger an exception if you trying to do so. In another word, you can’t do something like “mkdir -p DIR”.
However, the callback function is an extreamly useful feature to extend this function. In case the fs.mkdir failed, it passes an error object into the callback function. Like this:
var fs = require('fs'); fs.mkdir('parent/child', function(error) { console.log(error); });
You’ll see it print an object looks like:
{ [Error: ENOENT, no such file or directory ‘parent/child’] errno: 34, code: ‘ENOENT’, path: ‘parent/child’ }
Good, now we know in the case of missing directory, we’ll get error code 34. What if we catch the error and try to recursively create it’s parent, then create the directory again? Everybody deserve a second chance, right?
var fs = require('fs'); var path = require('path'); fs.mkdirParent = function(dirPath, mode, callback) { //Call the standard fs.mkdir fs.mkdir(dirPath, mode, function(error) { //When it fail in this way, do the custom steps if (error && error.errno === 34) { //Create all the parents recursively fs.mkdirParent(path.dirname(dirPath), mode, callback); //And then the directory fs.mkdirParent(dirPath, mode, callback); } //Manually run the callback since we used our own callback to do all these callback && callback(error); }); };
Now you can run it like this;
fs.mkdirParent('a/b/c/d/e');
8 responses to “Making directory along with missing parents in Node.js”
Awesome codes! The original codes has some issue with the callback. Your code makes sure the callback only called once.
A constructive comment would be more interesting….
Trying to show how things work is always welcome and installing modules is not always the best approach or needed.
it should be:
function mkdir(dirPath, mode,callback)
{
fs.mkdir(dirPath, mode, function (error)
{
if (error && error.code == ‘ENOENT’)
{
mkdir(path.dirname(dirPath), mode, mkdir.bind(this,dirPath,mode,callback));
}
else if (callback) callback(error);
});
}
Superb.
Works fine.
Hi Luis, the only once callback is a feature missing from this snippet, you can consider that as a bug. For the full feature script, please consider using mkdirp http://search.npmjs.org/#/mkdirp
Great, the script works fine except that I think the most used pattern would be to do something (callback) once the last directory is created.
From my test what currently happens is that the callback is executed for every directory created.
Am I doing something wrong or is this the expected behaviour, and if so, how can I only have one callback once the path is fully created?
Thanks
Luis
Don’t meant to reinvent the wheel. The point of this snippet is NOT to install any module and still able to have a short script up and running.
https://github.com/substack/node-mkdirp has existed for a while.
please use http://toolbox.no.de/ to search for modules next time. :)