Create Directory When Writing To File In Node.js

前端 未结 9 1405
情话喂你
情话喂你 2021-01-30 09:44

I\'ve been tinkering with Node.js and found a little problem. I\'ve got a script which resides in a directory called data. I want the script to write some data to

相关标签:
9条回答
  • 2021-01-30 10:15

    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. it overwrites), except that if the parent directory does not exist, it's 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 so, 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 a sync version, just use this code:

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

    For a complete reference, check the outputFile documentation and all node-fs-extra supported methods.

    0 讨论(0)
  • 2021-01-30 10:19

    Since I cannot comment yet, I'm posting an enhanced answer based on @tiago-peres-frança fantastic solution (thanks!). His code does not make directory in a case where only the last directory is missing in the path, e.g. the input is "C:/test/abc" and "C:/test" already exists. Here is a snippet that works:

    function mkdirp(filepath) {
        var dirname = path.dirname(filepath);
    
        if (!fs.existsSync(dirname)) {
            mkdirp(dirname);
        }
    
        fs.mkdirSync(filepath);
    }
    
    0 讨论(0)
  • 2021-01-30 10:21

    I just published this module because I needed this functionality.

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

    It works like a wrapper around Node.js fs methods. So you can use it exactly the same way you would with fs.writeFile and fs.writeFileSync (both async and synchronous writes)

    0 讨论(0)
  • 2021-01-30 10:26

    Node > 10.12.0

    fs.mkdir now accepts a { recursive: true } option like so:

    // 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 with a package like mkdirp or fs-extra. If you don't want to install a package, please see Tiago Peres França's answer below.

    0 讨论(0)
  • 2021-01-30 10:28

    Same answer as above, but with async await and ready to use!

    const fs = require('fs/promises');
    const path = require('path');
    
    async function isExists(path) {
      try {
        await fs.access(path);
        return true;
      } catch {
        return false;
      }
    };
    
    async function writeFile(filePath, data) {
      try {
        const dirname = path.dirname(filePath);
        const exist = await isExists(dirname);
        if (!exist) {
          await fs.mkdir(dirname, {recursive: true});
        }
        
        await fs.writeFile(filePath, data, 'utf8');
      } catch (err) {
        throw new Error(err);
      }
    }
    

    Example:

    (async () {
      const data = 'Hello, World!';
      await writeFile('dist/posts/hello-world.html', data);
    })();
    
    0 讨论(0)
  • 2021-01-30 10:30

    My advise is: try not to rely on dependencies when you can easily do it with few lines of codes

    Here's what you're trying to achieve in 14 lines of code:

    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);
        });
    };
    
    0 讨论(0)
提交回复
热议问题