Jika Anda melakukan operasi ini pada boot aplikasi atau inisialisasi, maka boleh saja untuk memblokir eksekusi karena Anda akan melakukan hal yang sama jika Anda melakukannya secara asinkron. Jika Anda menjadikan direktori sebagai operasi berulang, maka ini merupakan praktik buruk, tetapi mungkin tidak akan menyebabkan masalah kinerja, namun ini merupakan kebiasaan buruk. Hanya digunakan untuk mem-boot aplikasi Anda atau operasi satu kali.
fs.exists()adalah anakronisme dan hanya ada karena alasan historis. Seharusnya hampir tidak pernah ada alasan untuk menggunakannya dalam kode Anda sendiri.
Khususnya, memeriksa apakah ada file sebelum membukanya, itu merupakan pola anti yang membuat Anda rentan terhadap kondisi balapan: proses lain dapat menghapus file antara panggilan ke fs.exists()dan fs.open(). Cukup buka file dan tangani kesalahannya saat tidak ada.
Karena kita berbicara tentang direktori daripada file, saran ini menyiratkan Anda hanya harus memanggil mkdirdan mengabaikan tanpa syarat EEXIST.
Secara umum, Anda harus menghindari Syncmetode * . Mereka memblokir, yang berarti sama sekali tidak ada hal lain dalam program Anda yang dapat terjadi saat Anda masuk ke disk. Ini adalah operasi yang sangat mahal, dan waktu yang diperlukan mematahkan asumsi inti dari simpul acara simpul.
The * Syncmetode yang biasanya baik-baik saja di-tujuan tunggal skrip cepat (orang-orang yang melakukan satu hal dan kemudian keluar), tetapi harus hampir tidak pernah digunakan ketika Anda sedang menulis sebuah server: server Anda akan dapat merespon kepada siapa pun untuk seluruh durasi dari permintaan I / O. Jika beberapa permintaan klien memerlukan operasi I / O, server Anda akan sangat cepat terhenti.
Satu-satunya waktu saya akan mempertimbangkan menggunakan Syncmetode * dalam aplikasi server adalah dalam operasi yang terjadi sekali (dan hanya sekali), pada saat startup. Misalnya, requiresebenarnya digunakanreadFileSync untuk memuat modul.
Meski begitu, Anda masih harus berhati-hati karena banyak I / O yang sinkron dapat memperlambat waktu startup server Anda.
Sebagai gantinya, Anda harus menggunakan metode I / O asinkron.
Jadi jika kita mengumpulkan saran-saran itu, kita mendapatkan sesuatu seperti ini:
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});}
Dan kita bisa menggunakannya seperti ini:
ensureExists(__dirname +'/upload',0744,function(err){if(err)// handle folder creation errorelse// we're all good});
Tentu saja, ini tidak termasuk kasus tepi seperti
Apa yang terjadi jika folder terhapus saat program Anda berjalan? (dengan asumsi Anda hanya memeriksa bahwa itu ada satu kali selama startup)
Apa yang terjadi jika folder sudah ada tetapi dengan izin yang salah?
Apakah bendera "topeng" ini masih relevan di tahun 2019? apa tujuannya?
oldboy
Ini adalah mode file unix - izin baca / tulis direktori.
josh3736
44
Saya telah menemukan dan modul npm yang berfungsi seperti pesona untuk ini. Itu hanya melakukan mkdir secara rekursif ketika dibutuhkan, seperti "mkdir -p".
The mkdirmetode memiliki kemampuan untuk secara rekursif membuat direktori apapun dalam jalur yang tidak ada, dan mengabaikan orang-orang yang melakukan.
// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple',{ recursive:true},(err)=>{if(err)throw err;});
CATATAN: Anda harus mengimpor fsmodul bawaan terlebih dahulu.
Sekarang inilah contoh yang lebih kuat yang memanfaatkan Modul ES asli (dengan flag diaktifkan dan ekstensi .mjs), menangani jalur non-root, dan menyumbang nama path lengkap:
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');}});}
Anda bisa menggunakannya seperti createDirectories('/components/widget/widget.js');.
Dan tentu saja, Anda mungkin ingin mendapatkan yang lebih mewah dengan menggunakan janji dengan async / menunggu untuk meningkatkan pembuatan file dengan cara yang terlihat lebih sinkron saat direktori dibuat; tapi, itu di luar ruang lingkup pertanyaan.
untuk pendekatan yang menjanjikan # 1, Anda dapat mengatur ulang tangkapan. mkdir('/path').catch(err => { if (err.code != 'EEXIST') throw err;}).then(myFunc);
Jawaban yang diremehkan seperti itu! fs-extra memiliki bacame yang harus dimiliki untukku. Saya pikir ini adalah abberasi untuk menulis 10+ baris juste untuk memeriksa apakah ada folder ...
538ROMEO
10
Solusi terbaik adalah dengan menggunakan modul npm yang disebut node-fs-extra . Ini memiliki metode yang disebut mkdiryang membuat direktori yang Anda sebutkan. Jika Anda memberikan jalur direktori yang panjang, itu akan membuat folder induk secara otomatis. Modul ini adalah set modul npm yang super fs, sehingga Anda dapat menggunakan semua fungsi fsjuga jika Anda menambahkan modul ini.
Untuk Node.js v7.4.0, dokumentasi menyatakan bahwa fs.exists()sudah usang, tetapi fs.existsSync()tidak. Bisakah Anda menambahkan tautan ke sumber daya pepatah yang fs.existsSync()didepresiasi?
francis
1
Jawaban hanya kode tidak sangat membantu bagi pengguna yang datang ke pertanyaan ini di masa mendatang. Harap edit jawaban Anda untuk menjelaskan mengapa kode Anda memecahkan masalah asli
Terima kasih! Tampaknya fungsi tersebut ada di versi 0.12, tidak digunakan lagi di versi 4 dan 5 dan dipulihkan di versi 6 dan 7 ... Jenis fungsi zombi ...
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;}}})();
Anda dapat menggunakan perintah node File System fs.stat untuk memeriksa apakah dir ada dan fs.mkdir untuk membuat direktori dengan panggilan balik, atau fs.mkdirSync untuk membuat direktori tanpa panggilan balik, seperti contoh ini:
//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);}});};
Berikut adalah sedikit fungsi untuk secara rekursif membuat direktori:
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
},'')}
Jawaban:
sumber
Sync
metode biasanya tidak-tidak: tidak ingin memblokir acara loopTidak, karena berbagai alasan.
The
path
modul tidak memilikiexists
/existsSync
metode. Itu ada difs
modul. (Mungkin Anda baru saja membuat kesalahan ketik pada pertanyaan Anda?)Dokumen secara eksplisit mencegah Anda menggunakan
exists
.Karena kita berbicara tentang direktori daripada file, saran ini menyiratkan Anda hanya harus memanggil
mkdir
dan mengabaikan tanpa syaratEEXIST
.Secara umum, Anda harus menghindari
Sync
metode * . Mereka memblokir, yang berarti sama sekali tidak ada hal lain dalam program Anda yang dapat terjadi saat Anda masuk ke disk. Ini adalah operasi yang sangat mahal, dan waktu yang diperlukan mematahkan asumsi inti dari simpul acara simpul.The *
Sync
metode yang biasanya baik-baik saja di-tujuan tunggal skrip cepat (orang-orang yang melakukan satu hal dan kemudian keluar), tetapi harus hampir tidak pernah digunakan ketika Anda sedang menulis sebuah server: server Anda akan dapat merespon kepada siapa pun untuk seluruh durasi dari permintaan I / O. Jika beberapa permintaan klien memerlukan operasi I / O, server Anda akan sangat cepat terhenti.Satu-satunya waktu saya akan mempertimbangkan menggunakan
Sync
metode * dalam aplikasi server adalah dalam operasi yang terjadi sekali (dan hanya sekali), pada saat startup. Misalnya,require
sebenarnya digunakanreadFileSync
untuk memuat modul.Meski begitu, Anda masih harus berhati-hati karena banyak I / O yang sinkron dapat memperlambat waktu startup server Anda.
Sebagai gantinya, Anda harus menggunakan metode I / O asinkron.
Jadi jika kita mengumpulkan saran-saran itu, kita mendapatkan sesuatu seperti ini:
Dan kita bisa menggunakannya seperti ini:
Tentu saja, ini tidak termasuk kasus tepi seperti
sumber
0744 == 484
.Saya telah menemukan dan modul npm yang berfungsi seperti pesona untuk ini. Itu hanya melakukan mkdir secara rekursif ketika dibutuhkan, seperti "mkdir -p".
https://www.npmjs.com/package/mkdirp
sumber
The
mkdir
metode memiliki kemampuan untuk secara rekursif membuat direktori apapun dalam jalur yang tidak ada, dan mengabaikan orang-orang yang melakukan.Dari Node v10 / 11 docs :
CATATAN: Anda harus mengimpor
fs
modul bawaan terlebih dahulu.Sekarang inilah contoh yang lebih kuat yang memanfaatkan Modul ES asli (dengan flag diaktifkan dan ekstensi .mjs), menangani jalur non-root, dan menyumbang nama path lengkap:
Anda bisa menggunakannya seperti
createDirectories('/components/widget/widget.js');
.Dan tentu saja, Anda mungkin ingin mendapatkan yang lebih mewah dengan menggunakan janji dengan async / menunggu untuk meningkatkan pembuatan file dengan cara yang terlihat lebih sinkron saat direktori dibuat; tapi, itu di luar ruang lingkup pertanyaan.
sumber
Untuk berjaga-jaga jika ada yang tertarik dengan versi satu baris. :)
sumber
Anda bisa menggunakan
mkdir
dan menangkap kesalahan jika folder ada.Ini async (praktik terbaik) dan aman.
(Secara opsional tambahkan argumen kedua dengan mode.)
Pikiran lain:
Anda bisa menggunakannya saat itu atau menunggu dengan menggunakan promisify asli .
Anda dapat membuat metode janji sendiri, seperti (belum diuji):
Untuk pemeriksaan sinkron, Anda dapat menggunakan:
Atau Anda dapat menggunakan perpustakaan, dua yang paling populer
sumber
mkdir('/path').catch(err => { if (err.code != 'EEXIST') throw err;}).then(myFunc);
!==
sebagai ganti!=
Dengan paket fs-extra Anda dapat melakukan ini dengan one-liner :
sumber
Solusi terbaik adalah dengan menggunakan modul npm yang disebut node-fs-extra . Ini memiliki metode yang disebut
mkdir
yang membuat direktori yang Anda sebutkan. Jika Anda memberikan jalur direktori yang panjang, itu akan membuat folder induk secara otomatis. Modul ini adalah set modul npm yang superfs
, sehingga Anda dapat menggunakan semua fungsifs
juga jika Anda menambahkan modul ini.sumber
sumber
fs.exists()
sudah usang, tetapifs.existsSync()
tidak. Bisakah Anda menambahkan tautan ke sumber daya pepatah yangfs.existsSync()
didepresiasi?Apr 2018
: nodejs.org/api/fs.html#fs_fs_existssync_pathIni dapat membantu Anda :)
sumber
Larutan
sumber
Saya ingin menambahkan refactor Typescript Promise atas jawaban josh3736 .
Itu melakukan hal yang sama dan memiliki kasus tepi yang sama, kebetulan menggunakan Janji, mengetikkan huruf dan bekerja dengan "gunakan ketat".
sumber
Dengan Node 10 + ES6:
sumber
Anda dapat menggunakan perintah node File System fs.stat untuk memeriksa apakah dir ada dan fs.mkdir untuk membuat direktori dengan panggilan balik, atau fs.mkdirSync untuk membuat direktori tanpa panggilan balik, seperti contoh ini:
sumber
Berikut adalah sedikit fungsi untuk secara rekursif membuat direktori:
sumber
Menggunakan async / tunggu:
Anda harus berjanji
fs
:sumber