Это правильный способ создать каталог, если он не существует. Он должен иметь полное разрешение для сценария и читаться другими.
var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
fs.mkdirSync(dir, 0744);
}
Это правильный способ создать каталог, если он не существует. Он должен иметь полное разрешение для сценария и читаться другими.
var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
fs.mkdirSync(dir, 0744);
}
Ответы:
var fs = require('fs');
var dir = './tmp';
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
Syncметодов обычно является
Нет, по нескольким причинам.
В pathмодуле нет метода exists/ existsSync. Это в fsмодуле. (Возможно, вы только что сделали опечатку в своем вопросе?)
Документы явно отговаривают вас от использования exists.
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 exists
else cb(err); // something else went wrong
} else cb(null); // successfully created folder
});
}
И мы можем использовать это так:
ensureExists(__dirname + '/upload', 0744, function(err) {
if (err) // handle folder creation error
else // we're all good
});
Конечно, это не учитывает крайние случаи, такие как
0744 == 484,
Я нашел и модуль npm, который работает как шарм для этого. Он просто делает рекурсивный mkdir, когда это необходимо, например, "mkdir -p".
mkdirМетод имеет возможность рекурсивно создавать любые каталоги в пути , которые не существуют, и игнорировать те , которые делают.
// 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, чтобы использовать создание файлов в более читабельном синхронном виде при создании каталогов; но это выходит за рамки вопроса.
На всякий случай, если кто-то заинтересован в однострочном варианте. :)
//or in typescript: import * as fs from 'fs';
const fs = require('fs');
!fs.existsSync(dir) && fs.mkdirSync(dir);
Вы можете просто использовать mkdirи поймать ошибку, если папка существует.
Это асинхронно (поэтому рекомендуется) и безопасно.
fs.mkdir('/path', err => {
if (err && err.code != 'EEXIST') throw 'up'
.. safely do your stuff here
})
(При желании добавьте второй аргумент с режимом.)
Другие мысли:
Вы можете использовать тогда или ждать с помощью встроенного обещания .
const util = require('util'), fs = require('fs');
const mkdir = util.promisify(fs.mkdir);
var myFunc = () => { ..do something.. }
mkdir('/path')
.then(myFunc)
.catch(err => { if (err.code != 'EEXIST') throw err; myFunc() })Вы можете сделать свой собственный метод обещания, что-то вроде (не проверено):
let mkdirAsync = (path, mode) => new Promise(
(resolve, reject) => mkdir (path, mode,
err => (err && err.code !== 'EEXIST') ? reject(err) : resolve()
)
)Для синхронной проверки вы можете использовать:
fs.existsSync(path) || fs.mkdirSync(path)Или вы можете использовать библиотеку, две самые популярные из которых
mkdir('/path').catch(err => { if (err.code != 'EEXIST') throw err;}).then(myFunc);
!==вместо!=
С пакетом fs-extra вы можете сделать это с помощью одной строки :
const fs = require('fs-extra');
const dir = '/tmp/this/path/does/not/exist';
fs.ensureDirSync(dir);
Лучшее решение - использовать модуль npm, называемый node-fs-extra . У него есть метод, mkdirкоторый создает каталог, который вы упомянули. Если вы укажете длинный путь к каталогу, он автоматически создаст родительские папки. Модуль представляет собой супер-набор модулей npm fs, поэтому вы можете использовать все функции, в том fsчисле и при добавлении этого модуля.
var dir = 'path/to/dir';
try {
fs.mkdirSync(dir);
} catch(e) {
if (e.code != 'EEXIST') throw e;
}
fs.exists()она устарела, но fs.existsSync()это не так. Не могли бы вы добавить ссылку на ресурс, говоря, что fs.existsSync()это амортизируется?
Apr 2018: с : nodejs.org/api/fs.html#fs_fs_existssync_path
var filessystem = require('fs');
var dir = './path/subpath/';
if (!filessystem.existsSync(dir)){
filessystem.mkdirSync(dir);
}else
{
console.log("Directory already exist");
}
Это может помочь вам :)
ENOENT: нет такого файла или каталога
Решение
const fs = require('fs') // in javascript
import * as fs from "fs" // in typescript
import fs from "fs" // in typescript
// it will create the directory if it does not exist.
!fs.existsSync(`./assets/`) && fs.mkdirSync(`./assets/`, { recursive: true })
Я хотел бы добавить рефактор Typescript Promise к ответу josh3736 .
Он делает то же самое и имеет те же самые крайние случаи, он просто использует Promises, typedefs typefs и работает с «use strict».
// https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
const allRWEPermissions = parseInt("0777", 8);
function ensureFilePathExists(path: string, mask: number = allRWEPermissions): Promise<void> {
return new Promise<void>(
function(resolve: (value?: void | PromiseLike<void>) => void,
reject: (reason?: any) => void): void{
mkdir(path, mask, function(err: NodeJS.ErrnoException): void {
if (err) {
if (err.code === "EEXIST") {
resolve(null); // ignore the error if the folder already exists
} else {
reject(err); // something else went wrong
}
} else {
resolve(null); // successfully created folder
}
});
});
}
С Узлом 10 + ES6:
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 fs
const 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
}, '')
}
Использование async / await:
const mkdirP = async (directory) => {
try {
return await fs.mkdirAsync(directory);
} catch (error) {
if (error.code != 'EEXIST') {
throw e;
}
}
};
Вам нужно будет обещать fs:
import nodeFs from 'fs';
import bluebird from 'bluebird';
const fs = bluebird.promisifyAll(nodeFs);