在Node.js中写入文件时创build目录
我一直在修补Node.js,发现一个小问题。 我有一个脚本,驻留在一个名为data
的目录。 我希望脚本将一些数据写入数据子目录内的子目录中的文件。 不过,我收到以下错误:
{[Error:ENOENT,open'D:\ data \ tmp \ test.txt'] errno:34,code:'ENOENT',path:'D:\ data \ tmp \ test.txt'}
代码如下:
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!"); } });
任何人都可以帮助我find如何使Node.js创build目录结构,如果它不写入文件退出?
mkdir -p
function的标准是相应命名的mkdirp 。 包统计可以在这里find。
如果您不想使用任何附加软件包,则可以在创build文件之前调用以下函数:
function ensureDirectoryExistence(filePath) { var dirname = path.dirname(filePath); if (fs.existsSync(dirname)) { return true; } ensureDirectoryExistence(dirname); fs.mkdirSync(dirname); }
PS:“path”和“fs”是需要的默认节点包。 请记住将以下内容添加到您的代码中:
var path = require('path'), fs = require('fs');
无耻的插件警报!
您将不得不检查所需的path结构中的每个目录,如果不存在,请手动创build它。 所有的工具都已经在Node的fs模块中,但是你可以简单地使用我的mkpath模块来完成所有的工作: https : //github.com/jrajav/mkpath
由于我还不能发表评论,所以我发布了一个基于@ tiago-peres-frança奇妙解决scheme的增强型答案(谢谢!)。 在path中只有最后一个目录缺失的情况下,他的代码不会生成目录,例如input是“C:/ test / abc”,“C:/ test”已经存在。 这是一个工作的片段:
function mkdirp(filepath) { var dirname = path.dirname(filepath); if (!fs.existsSync(dirname)) { mkdirp(dirname); } fs.mkdirSync(filepath); }
使用node-fs-extra可以做到这一点。
安装它
npm install --save fs-extra
然后使用outputFile
方法。 其文档说:
几乎与writeFile(即覆盖)相同,除了如果父目录不存在,它是创build。
您可以通过三种方式使用它:
callback风格
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!'); } })
使用承诺
如果你使用承诺 ,我希望如此,这是代码:
fse.outputFile('tmp/test.txt', 'Hey there!') .then(() => { console.log('The file was saved!'); }) .catch(err => { console.error(err) });
同步版本
如果你想要一个同步版本,只需使用下面的代码:
fse.outputFileSync('tmp/test.txt', 'Hey there!')
有关完整的参考,请检查outputFile
文档和所有node-fs-extra支持的方法 。
我刚刚发布这个模块,因为我需要这个function。
https://www.npmjs.org/package/filendir
它像Node.js fs方法的包装一样工作。 所以你可以像使用fs.writeFile
和fs.writeFileSync
(同步和asynchronous写入)一样使用它,
我的build议是: 尽量less用几行代码,尽量不要依赖依赖关系
以下是您想要在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); }); };