Как написать файл, если родительская папка не существует?
мне нужно записать файл по следующему пути:
fs.writeFile('/folder1/folder2/file.txt', 'content', function () {
});
но '/folder1/folder2'
путь не существует. Поэтому я получаю следующую ошибку:
message=ENOENT, open /folder1/folder2/file.txt
как я могу написать контент на этот путь?
7 ответов:
использовать mkdirp в сочетании с
path.dirname
первый.var mkdirp = require('mkdirp'); var fs = require('fs'); var getDirName = require('path').dirname; function writeFile(path, contents, cb) { mkdirp(getDirName(path), function (err) { if (err) return cb(err); fs.writeFile(path, contents, cb); }); }
Если весь путь уже существует,
mkdirp
является noop. В противном случае он создает все отсутствующие каталоги для вас.этот модуль делает то, что вы хотите: https://npmjs.org/package/writefile . Получил его, когда гуглил для "writefile mkdirp". Этот модуль возвращает обещание вместо обратного вызова, поэтому не забудьте сначала прочитать введение в обещания. Это может быть на самом деле усложнить вещи для вас.
функция, которую я дал работает в любом случае.
возможно, самое простое, вы можете просто использовать fs-path модуль npm.
ваш код будет выглядеть так:var fsPath = require('fs-path'); fsPath.writeFile('/folder1/folder2/file.txt', 'content', function(err){ if(err) { throw err; } else { console.log('wrote a file like DaVinci drew machines'); } });
Я считаю, что самый простой способ сделать это-использовать выходной_файл() метод от fs-extra модуль.
почти то же самое, что и writeFile (т. е. он перезаписывает), за исключением того, что если родительский каталог не существует, он создается. варианты - это то, что вы передадите в fs.writeFile ().
пример:
var fs = require('fs-extra'); var file = '/tmp/this/path/does/not/exist/file.txt' fs.outputFile(file, 'hello!', function (err) { console.log(err); // => null fs.readFile(file, 'utf8', function (err, data) { console.log(data); // => hello! }); });
Он также обещана поддержка из коробки в эти дни!.
можно использовать
fs.stat('/folder1/folder2', function(err, stats){ ... });
stats
этоfs.Stats
тип объекта, вы можете проверитьstats.isDirectory()
. В зависимости от экспертизыerr
иstats
ты можешь что-то сделать,fs.mkdir( ... )
или выдать ошибку.обновление: исправлены запятые в коде.
создать каталоги рекурсивно, если они не существуют! (ноль зависимостей)
const fs = require('fs'); const path = require('path'); function mkDirByPathSync(targetDir, {isRelativeToScript = false} = {}) { const sep = path.sep; const initDir = path.isAbsolute(targetDir) ? sep : ''; const baseDir = isRelativeToScript ? __dirname : '.'; targetDir.split(sep).reduce((parentDir, childDir) => { const curDir = path.resolve(baseDir, parentDir, childDir); try { fs.mkdirSync(curDir); console.log(`Directory ${curDir} created!`); } catch (err) { if (err.code !== 'EEXIST') { throw err; } console.log(`Directory ${curDir} already exists!`); } return curDir; }, initDir); }
использование
// Default, make directories relative to current working directory. mkDirByPathSync('path/to/dir'); // Make directories relative to the current script. mkDirByPathSync('path/to/dir', {isRelativeToScript: true}); // Make directories with an absolute path. mkDirByPathSync('/path/to/dir');
демо
объяснениями
- это решение обрабатывает как относительные и абсолютное пути. Спасибо @john comment.
- в случае относительных путей будут созданы целевые каталоги (разрешено) в текущем рабочем каталоге. Чтобы разрешить их относительно текущего скрипта dir, передайте
{isRelativeToScript: true}
.- используя
path.sep
иpath.resolve()
не только/
конкатенация, чтобы избежать кросс-платформенные вопросы.- используя
fs.mkdirSync
и обработка ошибки сtry/catch
если брошен для обработки условий гонки: другой процесс может добавить файл между вызовамиfs.existsSync()
иfs.mkdirSync()
и вызывает исключение.
- другим способом достижения этого может быть проверка наличия файла, а затем его создание, т. е.
if (!fs.existsSync(curDir) fs.mkdirSync(curDir);
. Но это анти-шаблон, который оставляет код уязвимым для условий гонки. Благодаря комментарию @GershomMaes о проверке существования каталога.- требует узел v6 и новее для поддержки деструктурируется. (Если у вас есть проблемы с реализацией этого решения со старыми версиями узлов, просто оставьте мне комментарий)
вот моя пользовательская функция для рекурсивного создания каталогов (без внешних зависимостей):
var fs = require('fs'); var path = require('path'); var myMkdirSync = function(dir){ if (fs.existsSync(dir)){ return } try{ fs.mkdirSync(dir) }catch(err){ if(err.code == 'ENOENT'){ myMkdirSync(path.dirname(dir)) //create parent dir myMkdirSync(dir) //create dir } } } myMkdirSync(path.dirname(filePath)); var file = fs.createWriteStream(filePath);
вот часть ответа Мирны стол вспыхнула как отдельный ответ:
этот модуль делает то, что вы хотите: https://npmjs.org/package/writefile . Получил его, когда гуглил для "writefile mkdirp". Этот модуль возвращает обещайте вместо того, чтобы принимать обратный вызов, так что не забудьте прочитать некоторые введение в обещания в первую очередь. Это может усложнять для тебя.