É este o caminho certo para criar um diretório, se ele não existir. Deve ter permissão total para o script e legível por outras pessoas.
var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
fs.mkdirSync(dir, 0744);
}
É este o caminho certo para criar um diretório, se ele não existir. Deve ter permissão total para o script e legível por outras pessoas.
var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
fs.mkdirSync(dir, 0744);
}
Respostas:
var fs = require('fs');
var dir = './tmp';
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
Syncmétodos geralmente é um não-não: não queremos bloquear o ciclo de eventos
Não, por várias razões.
O pathmódulo não possui um método exists/ existsSync. Está no fsmódulo. (Talvez você tenha cometido um erro de digitação na sua pergunta?)
Os documentos explicitamente o desencorajam de usar exists.
fs.exists()é um anacronismo e existe apenas por razões históricas. Quase nunca deve haver um motivo para usá-lo em seu próprio código.Em particular, verificar se um arquivo existe antes de abri-lo é um antipadrão que o deixa vulnerável às condições de corrida: outro processo pode remover o arquivo entre as chamadas para
fs.exists()efs.open(). Basta abrir o arquivo e manipular o erro quando ele não estiver lá.
Como estamos falando de um diretório em vez de um arquivo, esse conselho implica que você deve ligar mkdire ignorar incondicionalmente EEXIST.
Em geral, você deve evitar os Syncmétodos * . Eles estão bloqueando, o que significa que absolutamente nada no seu programa pode acontecer enquanto você acessa o disco. Essa é uma operação muito cara e o tempo que leva para quebrar a suposição principal do loop de eventos do nó.
Os Syncmétodos * geralmente são bons em scripts rápidos de uso único (aqueles que fazem uma coisa e depois saem), mas quase nunca devem ser usados quando você está gravando um servidor: seu servidor não poderá responder a ninguém por todo o período dos pedidos de E / S. Se várias solicitações de clientes exigirem operações de E / S, o servidor será interrompido muito rapidamente.
A única vez em que eu consideraria o uso de Syncmétodos * em um aplicativo de servidor é em uma operação que acontece uma vez (e apenas uma vez), na inicialização. Por exemplo, require na verdadereadFileSync , usa para carregar módulos.
Mesmo assim, você ainda precisa ter cuidado, pois muitas E / S síncronas podem diminuir desnecessariamente o tempo de inicialização do servidor.
Em vez disso, você deve usar os métodos de E / S assíncrona.
Portanto, se juntarmos esses conselhos, teremos algo assim:
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
});
}
E podemos usá-lo assim:
ensureExists(__dirname + '/upload', 0744, function(err) {
if (err) // handle folder creation error
else // we're all good
});
Obviamente, isso não leva em conta casos extremos como
0744 == 484.
Eu encontrei e módulo npm que funciona como um encanto para isso. É simplesmente fazer um mkdir recursivamente quando necessário, como um "mkdir -p".
O mkdirmétodo tem a capacidade de criar recursivamente todos os diretórios em um caminho que não existe e ignorar os que existem.
Nos documentos do nó v10 / 11 :
// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
});
NOTA: Você precisará importar o fsmódulo interno primeiro.
Agora, aqui está um exemplo um pouco mais robusto que aproveita os Módulos ES nativos (com sinalizador ativado e extensão .mjs), manipula caminhos não raiz e responde por nomes de caminho completos:
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');
}
});
}
Você pode usá-lo como createDirectories('/components/widget/widget.js');.
E, é claro, você provavelmente desejaria ter mais fantasia usando promessas com async / waitit para alavancar a criação de arquivos de uma maneira síncrona mais legível quando os diretórios forem criados; mas isso está além do escopo da pergunta.
Apenas no caso de alguém interessado na versão de uma linha. :)
//or in typescript: import * as fs from 'fs';
const fs = require('fs');
!fs.existsSync(dir) && fs.mkdirSync(dir);
Você pode simplesmente usar mkdire capturar o erro se a pasta existir.
Isso é assíncrono (portanto, é uma prática recomendada) e seguro.
fs.mkdir('/path', err => {
if (err && err.code != 'EEXIST') throw 'up'
.. safely do your stuff here
})
(Opcionalmente, adicione um segundo argumento com o modo.)
Outros pensamentos:
Você pode usar ou aguardar usando o promisify nativo .
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() })Você pode criar seu próprio método de promessa, algo como (não testado):
let mkdirAsync = (path, mode) => new Promise(
(resolve, reject) => mkdir (path, mode,
err => (err && err.code !== 'EEXIST') ? reject(err) : resolve()
)
)Para verificação síncrona, você pode usar:
fs.existsSync(path) || fs.mkdirSync(path)Ou você pode usar uma biblioteca, as duas mais populares
mkdir('/path').catch(err => { if (err.code != 'EEXIST') throw err;}).then(myFunc);
!==vez de!=
Com o pacote fs-extra , você pode fazer isso com uma linha :
const fs = require('fs-extra');
const dir = '/tmp/this/path/does/not/exist';
fs.ensureDirSync(dir);
A melhor solução seria usar o módulo npm chamado node-fs-extra . Ele possui um método chamado mkdirque cria o diretório que você mencionou. Se você especificar um caminho de diretório longo, ele criará as pastas pai automaticamente. O módulo é um superconjunto de módulo npm fs, portanto, você pode usar todas as funções fstambém se adicionar este módulo.
var dir = 'path/to/dir';
try {
fs.mkdirSync(dir);
} catch(e) {
if (e.code != 'EEXIST') throw e;
}
fs.exists()reprovado, mas fs.existsSync()não é. Você poderia adicionar um link a um recurso dizendo que fs.existsSync()está depreciado?
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");
}
Isso pode ajudá-lo :)
ENOENT: esse arquivo ou diretório não existe
Solução
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 })
Gostaria de adicionar um refatorador de promessa de texto datilografado da resposta de josh3736 .
Ele faz a mesma coisa e tem os mesmos casos extremos, por acaso usa Promessas, typedefs datilografados e trabalha com "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
}
});
});
}
Com o nó 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;
}
}
})();
Você pode usar o comando Sistema de Arquivos do nó fs.stat para verificar se dir existe e fs.mkdir para criar um diretório com retorno de chamada ou fs.mkdirSync para criar um diretório sem retorno de chamada, como neste exemplo:
//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);
}
});
};
Aqui está uma pequena função para criar diretórios recursivamente:
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
}, '')
}
Usando assíncrono / espera:
const mkdirP = async (directory) => {
try {
return await fs.mkdirAsync(directory);
} catch (error) {
if (error.code != 'EEXIST') {
throw e;
}
}
};
Você precisará promisificar fs:
import nodeFs from 'fs';
import bluebird from 'bluebird';
const fs = bluebird.promisifyAll(nodeFs);