Create directory when writing to Node.js file

I was messing around with Node.js and found a little problem. I have a script that is in a directory called data . I want the script to write some data to a file in a subdirectory inside the data subdirectory. However, I get the following error:

 { [Error: ENOENT, open 'D:\data\tmp\test.txt'] errno: 34, code: 'ENOENT', path: 'D:\\data\\tmp\\test.txt' } 

The code is as follows:

 var fs = require('fs'); fs.writeFile("tmp/test.txt", "Hey there!", function(err) { if(err) { console.log(err); } else { console.log("The file was saved!"); } }); 

Can someone help me figure out how to get Node.js to create a directory structure if it doesn’t go out to write to a file?

+82
javascript
Nov 24 '12 at 15:34
source share
7 answers

Node> 10.12.0

fs.mkdir now accepts the parameter { recursive: true } for example:

 // Creates /tmp/a/apple, regardless of whether '/tmp' and /tmp/a exist. fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => { if (err) throw err; }); 

or with a promise:

 fs.promises.mkdir('/tmp/a/apple', { recursive: true }).catch(console.error); 

Node <= 10.11.0

You can solve this problem with a package like mkdirp or fs-extra . If you do not want to install the package, see Tiago Peres França's answer below.

+72
Nov 24
source share

If you do not want to use any additional package, you can call the following function before creating the file:

 var path = require('path'), fs = require('fs'); function ensureDirectoryExistence(filePath) { var dirname = path.dirname(filePath); if (fs.existsSync(dirname)) { return true; } ensureDirectoryExistence(dirname); fs.mkdirSync(dirname); } 
+97
Dec 29 '15 at 11:04
source share

Shameless Connection Warning!

You will need to check each directory in the path structure you want and create it manually if it does not exist. All the tools for this already exist in the Node fs module, but you can do it all simply with my mkpath module: https://github.com/jrajav/mkpath

+25
Nov 24 '12 at 15:35
source share

With node-fs-extra, you can do it easily.

Install it

 npm install --save fs-extra 

Then use the outputFile method. Its documentation says:

Almost the same as writeFile (i.e. overwrites), except that if the parent directory does not exist, it is created.

You can use it in three ways:

Callback style

 const fse = require('fs-extra'); fse.outputFile('tmp/test.txt', 'Hey there!', err => { if(err) { console.log(err); } else { console.log('The file was saved!'); } }) 

Using promises

If you use promises , and I hope this is the code:

 fse.outputFile('tmp/test.txt', 'Hey there!') .then(() => { console.log('The file was saved!'); }) .catch(err => { console.error(err) }); 

Sync version

If you want to sync the version, just use this code:

 fse.outputFileSync('tmp/test.txt', 'Hey there!') 

For full help, check the documentation of outputFile and all supported node-fs-extra methods .

+25
Aug 2 '17 at 16:09 on
source share

Since I cannot comment yet, I am posting an extended answer based on a fantastic solution @ tiago-peres-frança (thanks!). Its code does not create a directory when only the last directory is missing on the path, for example. the input "C: / test / abc" and "C: / test" already exist. Here is a snippet that works:

 function mkdirp(filepath) { var dirname = path.dirname(filepath); if (!fs.existsSync(dirname)) { mkdirp(dirname); } fs.mkdirSync(filepath); } 
+8
Dec 06 '16 at 10:52
source share

My advice: try not to rely on dependencies when you can easily do this with a few lines of code

Here is what you are trying to achieve on lines 14 :

 fs.isDir = function(dpath) { try { return fs.lstatSync(dpath).isDirectory(); } catch(e) { return false; } }; fs.mkdirp = function(dirname) { dirname = path.normalize(dirname).split(path.sep); dirname.forEach((sdir,index)=>{ var pathInQuestion = dirname.slice(0,index+1).join(path.sep); if((!fs.isDir(pathInQuestion)) && pathInQuestion) fs.mkdirSync(pathInQuestion); }); }; 
+7
Nov 02 '16 at 17:02
source share

I just published this module because I need this functionality.

https://www.npmjs.org/package/filendir

It works like a wrapper around Node.js fs methods. Thus, you can use it in exactly the same way as with fs.writeFile and fs.writeFileSync (for both asynchronous and synchronous recording)

+2
May 10 '14 at 10:19
source share



All Articles