Если вы выполняете эту операцию при загрузке или инициализации приложения, то можно блокировать выполнение, как если бы вы делали это асинхронно, то вы сделали бы то же самое. Если вы делаете каталог как повторяющуюся операцию, то это плохая практика, но, вероятно, она не вызовет проблем с производительностью, но, тем не менее, это плохая привычка. Используйте только для загрузки вашего приложения или других операций.
fs.exists()является анахронизмом и существует только по историческим причинам. Почти никогда не должно быть причин использовать его в своем собственном коде.
В частности, проверка наличия файла перед его открытием - это антишаблон, который делает вас уязвимым для условий гонки: другой процесс может удалить файл между вызовами fs.exists()и fs.open(). Просто откройте файл и обработайте ошибку, когда ее там нет.
Поскольку речь идет о каталоге, а не о файле, этот совет подразумевает, что вы должны просто безоговорочно вызывать mkdirи игнорировать EEXIST.
В общем, вам следует избегать * Syncметодов. Они блокируют, что означает, что в вашей программе больше ничего не может произойти, пока вы идете на диск. Это очень дорогая операция, и время, затрачиваемое на нее, нарушает основную идею цикла событий узла.
SyncМетоды * обычно хороши в быстрых сценариях с одним назначением (те, которые выполняют одно действие, а затем завершают работу), но почти никогда не должны использоваться при написании сервера: ваш сервер не сможет никому отвечать на протяжении всей продолжительности запросов ввода / вывода. Если множественные клиентские запросы требуют операций ввода-вывода, ваш сервер очень быстро остановится.
Единственный раз, когда я рассмотрю использование * Syncметодов в серверном приложении, это операция, которая выполняется один раз (и только один раз) при запуске. Например, requireфактически используетreadFileSync для загрузки модулей.
Даже в этом случае вы все равно должны быть осторожны, потому что большое количество синхронных операций ввода-вывода может излишне замедлить время запуска вашего сервера.
Вместо этого вы должны использовать асинхронные методы ввода / вывода.
Поэтому, если мы соберем эти советы, мы получим что-то вроде этого:
function ensureExists(path, mask, cb){if(typeof mask =='function'){// allow the `mask` parameter to be optional
cb = mask;
mask =0777;}
fs.mkdir(path, mask,function(err){if(err){if(err.code =='EEXIST') cb(null);// ignore the error if the folder already existselse cb(err);// something else went wrong}else cb(null);// successfully created folder});}
И мы можем использовать это так:
ensureExists(__dirname +'/upload',0744,function(err){if(err)// handle folder creation errorelse// we're all good});
Конечно, это не учитывает крайние случаи, такие как
Что произойдет, если папка будет удалена во время работы вашей программы? (при условии, что вы проверяете, что он существует только один раз при запуске)
Что произойдет, если папка уже существует, но с неправильными разрешениями?
// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple',{ recursive:true},(err)=>{if(err)throw err;});
ПРИМЕЧАНИЕ. fsСначала вам нужно будет импортировать встроенный модуль.
Теперь вот немного более надежный пример, который использует собственные модули ES (с включенным флагом и расширением .mjs), обрабатывает пути без полномочий root и учитывает полные пути:
import fs from'fs';import path from'path';
createDirectories(pathname){const __dirname = path.resolve();
pathname = pathname.replace(/^\.*\/|\/?[^\/]+\.[a-z]+|\/$/g,'');// Remove leading directory markers, and remove ending /file-name.extension
fs.mkdir(path.resolve(__dirname, pathname),{ recursive:true}, e =>{if(e){
console.error(e);}else{
console.log('Success');}});}
Вы можете использовать это как createDirectories('/components/widget/widget.js');.
И, конечно, вы, вероятно, захотите получить больше фантазии, используя обещания с async / await, чтобы использовать создание файлов в более читабельном синхронном виде при создании каталогов; но это выходит за рамки вопроса.
Такой недооцененный ответ! У fs-extra есть что-то, что должно быть для меня. Я думаю, что это аберрация писать более 10 строк, чтобы проверить, существует ли папка ...
538ROMEO
10
Лучшее решение - использовать модуль npm, называемый node-fs-extra . У него есть метод, mkdirкоторый создает каталог, который вы упомянули. Если вы укажете длинный путь к каталогу, он автоматически создаст родительские папки. Модуль представляет собой супер-набор модулей npm fs, поэтому вы можете использовать все функции, в том fsчисле и при добавлении этого модуля.
Для Node.js v7.4.0 в документации указано, что fs.exists()она устарела, но fs.existsSync()это не так. Не могли бы вы добавить ссылку на ресурс, говоря, что fs.existsSync()это амортизируется?
Франциск
1
Ответы только на код не очень полезны для пользователей, которые придут к этому вопросу в будущем. Пожалуйста, измените свой ответ, чтобы объяснить, почему ваш код решает исходную проблему
var filessystem = require('fs');var dir ='./path/subpath/';if(!filessystem.existsSync(dir)){
filessystem.mkdirSync(dir);}else{
console.log("Directory already exist");}
const fs = require('fs')// in javascriptimport* as fs from"fs"// in typescriptimport fs from"fs"// in typescript// it will create the directory if it does not exist.!fs.existsSync(`./assets/`)&& fs.mkdirSync(`./assets/`,{ recursive:true})
import path from'path';import fs from'fs';(async()=>{const dir = path.join(__dirname,'upload');try{await fs.promises.mkdir(dir);}catch(error){if(error.code ==='EEXIST'){// Something already exists, but is it a file or directory?const lstat =await fs.promises.lstat(dir);if(!lstat.isDirectory()){throw error;}}else{throw error;}}})();
Вы можете использовать команду файловой системы узла fs.stat, чтобы проверить, существует ли dir, и fs.mkdir, чтобы создать каталог с обратным вызовом, или fs.mkdirSync, чтобы создать каталог без обратного вызова, как в этом примере:
//first require fsconst fs = require('fs');// Create directory if not exist (function)const createDir =(path)=>{// check if dir exist
fs.stat(path,(err, stats)=>{if(stats.isDirectory()){// do nothing}else{// if the given path is not a directory, create a directory
fs.mkdirSync(path);}});};
Вот небольшая функция для рекурсивного создания каталогов:
const createDir =(dir)=>{// This will create a dir given a path such as './folder/subfolder' const splitPath = dir.split('/');
splitPath.reduce((path, subPath)=>{let currentPath;if(subPath !='.'){
currentPath = path +'/'+ subPath;if(!fs.existsSync(currentPath)){
fs.mkdirSync(currentPath);}}else{
currentPath = subPath;}return currentPath
},'')}
Ответы:
источник
Sync
методов обычно являетсяНет, по нескольким причинам.
В
path
модуле нет методаexists
/existsSync
. Это вfs
модуле. (Возможно, вы только что сделали опечатку в своем вопросе?)Документы явно отговаривают вас от использования
exists
.Поскольку речь идет о каталоге, а не о файле, этот совет подразумевает, что вы должны просто безоговорочно вызывать
mkdir
и игнорироватьEEXIST
.В общем, вам следует избегать *
Sync
методов. Они блокируют, что означает, что в вашей программе больше ничего не может произойти, пока вы идете на диск. Это очень дорогая операция, и время, затрачиваемое на нее, нарушает основную идею цикла событий узла.Sync
Методы * обычно хороши в быстрых сценариях с одним назначением (те, которые выполняют одно действие, а затем завершают работу), но почти никогда не должны использоваться при написании сервера: ваш сервер не сможет никому отвечать на протяжении всей продолжительности запросов ввода / вывода. Если множественные клиентские запросы требуют операций ввода-вывода, ваш сервер очень быстро остановится.Единственный раз, когда я рассмотрю использование *
Sync
методов в серверном приложении, это операция, которая выполняется один раз (и только один раз) при запуске. Например,require
фактически используетreadFileSync
для загрузки модулей.Даже в этом случае вы все равно должны быть осторожны, потому что большое количество синхронных операций ввода-вывода может излишне замедлить время запуска вашего сервера.
Вместо этого вы должны использовать асинхронные методы ввода / вывода.
Поэтому, если мы соберем эти советы, мы получим что-то вроде этого:
И мы можем использовать это так:
Конечно, это не учитывает крайние случаи, такие как
источник
0744 == 484
,Я нашел и модуль npm, который работает как шарм для этого. Он просто делает рекурсивный mkdir, когда это необходимо, например, "mkdir -p".
https://www.npmjs.com/package/mkdirp
источник
mkdir
Метод имеет возможность рекурсивно создавать любые каталоги в пути , которые не существуют, и игнорировать те , которые делают.С Node v10 / 11 документов :
ПРИМЕЧАНИЕ.
fs
Сначала вам нужно будет импортировать встроенный модуль.Теперь вот немного более надежный пример, который использует собственные модули ES (с включенным флагом и расширением .mjs), обрабатывает пути без полномочий root и учитывает полные пути:
Вы можете использовать это как
createDirectories('/components/widget/widget.js');
.И, конечно, вы, вероятно, захотите получить больше фантазии, используя обещания с async / await, чтобы использовать создание файлов в более читабельном синхронном виде при создании каталогов; но это выходит за рамки вопроса.
источник
На всякий случай, если кто-то заинтересован в однострочном варианте. :)
источник
Вы можете просто использовать
mkdir
и поймать ошибку, если папка существует.Это асинхронно (поэтому рекомендуется) и безопасно.
(При желании добавьте второй аргумент с режимом.)
Другие мысли:
Вы можете использовать тогда или ждать с помощью встроенного обещания .
Вы можете сделать свой собственный метод обещания, что-то вроде (не проверено):
Для синхронной проверки вы можете использовать:
Или вы можете использовать библиотеку, две самые популярные из которых
источник
mkdir('/path').catch(err => { if (err.code != 'EEXIST') throw err;}).then(myFunc);
!==
вместо!=
С пакетом fs-extra вы можете сделать это с помощью одной строки :
источник
Лучшее решение - использовать модуль npm, называемый node-fs-extra . У него есть метод,
mkdir
который создает каталог, который вы упомянули. Если вы укажете длинный путь к каталогу, он автоматически создаст родительские папки. Модуль представляет собой супер-набор модулей npmfs
, поэтому вы можете использовать все функции, в томfs
числе и при добавлении этого модуля.источник
источник
fs.exists()
она устарела, ноfs.existsSync()
это не так. Не могли бы вы добавить ссылку на ресурс, говоря, чтоfs.existsSync()
это амортизируется?Apr 2018
: с : nodejs.org/api/fs.html#fs_fs_existssync_pathЭто может помочь вам :)
источник
Решение
источник
Я хотел бы добавить рефактор Typescript Promise к ответу josh3736 .
Он делает то же самое и имеет те же самые крайние случаи, он просто использует Promises, typedefs typefs и работает с «use strict».
источник
С Узлом 10 + ES6:
источник
Вы можете использовать команду файловой системы узла fs.stat, чтобы проверить, существует ли dir, и fs.mkdir, чтобы создать каталог с обратным вызовом, или fs.mkdirSync, чтобы создать каталог без обратного вызова, как в этом примере:
источник
Вот небольшая функция для рекурсивного создания каталогов:
источник
Использование async / await:
Вам нужно будет обещать
fs
:источник