我一直在摆弄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!");
}
});
有人能帮我找出如何使Node.js创建目录结构,如果它不退出写入文件?
使用node-fs-extra,你可以很容易地做到这一点。
安装它
npm install --save fs-extra
然后使用outputFile方法。它的文档说:
几乎与writeFile相同(即它覆盖),除了如果
父目录不存在,它是创建的。
你可以用四种方法来使用它。
异步- await
const fse = require('fs-extra');
await fse.outputFile('tmp/test.txt', 'Hey there!');
使用承诺
如果你使用承诺,代码如下:
const fse = require('fs-extra');
fse.outputFile('tmp/test.txt', 'Hey there!')
.then(() => {
console.log('The file has been saved!');
})
.catch(err => {
console.error(err)
});
回调风格
const fse = require('fs-extra');
fse.outputFile('tmp/test.txt', 'Hey there!', err => {
if(err) {
console.log(err);
} else {
console.log('The file has been saved!');
}
})
同步版本
如果你想要一个同步版本,只需使用下面的代码:
const fse = require('fs-extra')
fse.outputFileSync('tmp/test.txt', 'Hey there!')
要获得完整的参考,请查看outputFile文档和所有node-fs-extra支持的方法。
与上面相同的答案,但异步等待和准备使用!
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);
}
}
例子:
(async () {
const data = 'Hello, World!';
await writeFile('dist/posts/hello-world.html', data);
})();
IDK为什么,但是这个mkdir总是使一个额外的目录与文件名,如果文件名也包含在路径中;如。
// fileName = './tmp/username/some-random.jpg';
try {
mkdirSync(fileName, { recursive: true })
} catch (error) {};
解决方案
可以这样解决:fileName.split('/')。Slice (0, -1).join('/')只生成到最后一个目录的目录,而不是文件名本身。
// fileName = './tmp/username/some-random.jpg';
try {
mkdirSync(fileName.split('/').slice(0, -1).join('/'), { recursive: true })
} catch (error) {};
使用node-fs-extra,你可以很容易地做到这一点。
安装它
npm install --save fs-extra
然后使用outputFile方法。它的文档说:
几乎与writeFile相同(即它覆盖),除了如果
父目录不存在,它是创建的。
你可以用四种方法来使用它。
异步- await
const fse = require('fs-extra');
await fse.outputFile('tmp/test.txt', 'Hey there!');
使用承诺
如果你使用承诺,代码如下:
const fse = require('fs-extra');
fse.outputFile('tmp/test.txt', 'Hey there!')
.then(() => {
console.log('The file has been saved!');
})
.catch(err => {
console.error(err)
});
回调风格
const fse = require('fs-extra');
fse.outputFile('tmp/test.txt', 'Hey there!', err => {
if(err) {
console.log(err);
} else {
console.log('The file has been saved!');
}
})
同步版本
如果你想要一个同步版本,只需使用下面的代码:
const fse = require('fs-extra')
fse.outputFileSync('tmp/test.txt', 'Hey there!')
要获得完整的参考,请查看outputFile文档和所有node-fs-extra支持的方法。
下面是一个完整的解决方案,在一个函数中创建包含所有所需子文件夹的文件夹,然后写入文件。
这是一个示例,假设您正在创建一个备份文件,并且希望在函数中传递备份文件夹名称(因此变量名称)
createFile(backupFolderName, fileName, fileContent) {
const csvFileName = `${fileName}.csv`;
const completeFilePath = join(process.cwd(), 'backups', backupFolderName);
fs.mkdirSync(completeFilePath, { recursive: true });
fs.writeFileSync(join(completeFilePath, csvFileName), fileContent, function (err) {
if (err) throw err;
console.log(csvFileName + ' file saved');
})
}