Node.js créer un dossier ou utiliser existant

J'ai déjà lu la documentation de Node.js et, à moins que si j'ai manqué quelque chose, il ne dit pas ce que les paramètres contiennent dans certaines opérations, en particulier fs.mkdir() . Comme vous pouvez le voir dans la documentation, ce n'est pas très grave.

Actuellement, j'ai ce code, qui tente de créer un dossier ou d'utiliser un existant à la place:

 fs.mkdir(path,function(e){ if(!e || (e && e.code === 'EEXIST')){ //do something with contents } else { //debug console.log(e); } }); 

Mais je me demande si c'est la bonne façon de le faire? Est-ce que le code EEXIST le bon moyen de savoir si le dossier existe déjà? Je sais que je peux faire fs.stat() avant de créer le répertoire, mais ce serait déjà deux hits sur le système de fichiers.

Deuxièmement, existe-t-il une documentation complète ou au moins plus détaillée de Node.js qui contient des détails sur les objets d'erreur, quels paramètres signifient etc.

La bonne façon de le faire est d'utiliser le module mkdirp .

 $ npm install mkdirp 

Utilisez-le pour exécuter la fonction qui requiert le répertoire. Le rappel est appelé après la création du chemin d'accès ou si le chemin d'accès existe déjà. L'erreur err est définie si mkdirp n'a pas réussi à créer le chemin du répertoire.

 var mkdirp = require('mkdirp'); mkdirp('/tmp/some/path/foo', function(err) { // path exists unless there was an error }); 

En try {} catch {} , vous pouvez le réaliser très gracieusement sans rencontrer une condition de course:

fs.mkdirSync(dirPath) tolérance de fs.mkdirSync(dirPath)

 const mkdirSync = function (dirPath) { try { fs.mkdirSync(dirPath) } catch (err) { if (err.code !== 'EEXIST') throw err } } 

Remarque: dirPath est utilisé comme un argument au lieu du path , tel qu'utilisé dans la documentation officielle de fs.mkdirSync de Node, pour éviter toute confusion avec le module de chemin standard de Node.

Explication

Node essaiera de créer le répertoire et lancera une exception si elle rencontre une exception. Dans la clause catch {} , nous continuons l'exécution du script comme si rien ne se passait si le code d'erreur est EEXIST , ce qui signifie que le répertoire existe. Cependant, si le code d'erreur n'est pas EEXIST , nous devons lancer une erreur, car nous traitons probablement d'une exception de système de fichiers comme EACCES (permission refusée).

Parce qu'il n'y a pas de temps mort entre la vérification de l'existence et la création du répertoire, nous évitons les conditions de course; Ceci cependant ne peut être vrai que lorsque vous utilisez la version synchrone (alors fs.mkdir() ne fonctionnerait pas), mais les opérations destructrices du système de fichiers telles que mkdir ne doivent être utilisées que de manière synchrone de toute façon.

Edit: J'ai découvert un moyen d'adapter le même concept au fs.mkdir asynchrone que vous pouvez trouver dans fs.mkdir

Exemples

Créons les répertoires. / ./first/second/third / ./first/second/fourth / ./first/second/fourth et. / ./first/second/fourth / ./first/second/fourth / ./first/second/fourth , donnés:

 const fs = require('fs') const path = require('path') const mkdirSync = function (dirPath) { try { fs.mkdirSync(dirPath) } catch (err) { if (err.code !== 'EEXIST') throw err } } 

Utilisation linéaire

Avec la fonction enveloppée ci-dessus, vous pouvez vous assurer que les annuaires existent et les créer de manière simple.

 mkdirSync(path.resolve('./first')) mkdirSync(path.resolve('./first/second')) mkdirSync(path.resolve('./first/second/third')) mkdirSync(path.resolve('./first/second')) // To demonstrate fault tolerance mkdirSync(path.resolve('./first/second/fourth')) 

Remarque: vous devez toujours vous assurer que chaque partie du chemin d'accès au répertoire existe. En appelant mkdirSync(path.resolve('./first/second/third')) directement sans vous ./first que mkdirSync(path.resolve('./first/second/third')) existent, ils ./first/second encore une exception.

Utilisation récursive comme le mkdir -p d'UNIX mkdir -p

Afin de contourner l'inconvénient mentionné ci-dessus, vous pouvez compléter notre mkdirSync() tolérante aux mkdirSync() dans une fonction récursive qui garantira que chaque partie du chemin existe:

 const mkdirpSync = function (dirPath) { const parts = dirPath.split(path.sep) // For every part of our path, call our wrapped mkdirSync() // on the full path until and including that part for (let i = 1; i <= parts.length; i++) { mkdirSync(path.join.apply(null, parts.slice(0, i))) } } // You can now directly create the two target directories mkdirpSync('first/second/third') mkdirpSync('first/second/fourth') 

Si vous voulez une doublure rapide et sale, utilisez ceci:

 fs.existsSync("directory") || fs.mkdirSync("directory"); 

Les fs.mkdir node.js pour fs.mkdir se fs.mkdir essentiellement à la page de manuel Linux pour mkdir(2) . Cela indique que EEXIST sera également indiqué si le chemin d'accès existe mais n'est pas un répertoire qui crée un cas d'angle gênant si vous parcourez cette route.

Vous pouvez être mieux d'appeler fs.stat qui vous dira si le chemin existe et s'il s'agit d'un répertoire en un seul appel. Pour (ce que je suppose) est le cas normal où le répertoire existe déjà, il ne s'agit que d'un seul système de fichiers.

Ces méthodes de module fs sont des enveloppes minces autour des API C natives, donc vous devez vérifier les pages man référencées dans les documents node.js pour les détails.

Vous pouvez utiliser ceci:

 if(!fs.existsSync("directory")){ fs.mkdirSync("directory", 0766, function(err){ if(err){ console.log(err); // echo the result back response.send("ERROR! Can't make the directory! \n"); } }); } 

Vous feriez mieux de ne pas compter les résultats du système de fichiers pendant que vous codez Javascript, à mon avis. Cependant, (1) stat & mkdir et (2) mkdir et vérifiez (ou rejettez) le code d'erreur, les deux façons sont les bonnes façons de faire ce que vous voulez.

Vous pouvez également utiliser fs-extra , qui fournissent beaucoup d'opérations de fichiers fréquemment utilisées.

Exemple de code:

 var fs = require('fs-extra') fs.mkdirs('/tmp/some/long/path/that/prob/doesnt/exist', function (err) { if (err) return console.error(err) console.log("success!") }) fs.mkdirsSync('/tmp/another/path') 

Docs ici: https://github.com/jprichardson/node-fs-extra#mkdirsdir-callback

Créez un répertoire de noms dynamiques pour chaque utilisateur … utilisez ce code

 ***suppose email contain user mail address*** var filessystem = require('fs'); var dir = './public/uploads/'+email; if (!filessystem.existsSync(dir)){ filessystem.mkdirSync(dir); }else { console.log("Directory already exist"); } 

Voici le code ES6 que j'utilise pour créer un répertoire (s'il n'existe pas):

 const fs = require('fs'); const path = require('path'); function createDirectory(directoryPath) { const directory = path.normalize(directoryPath); return new Promise((resolve, reject) => { fs.stat(directory, (error) => { if (error) { if (error.code === 'ENOENT') { fs.mkdir(directory, (error) => { if (error) { reject(error); } else { resolve(directory); } }); } else { reject(error); } } else { resolve(directory); } }); }); } const directoryPath = `${__dirname}/test`; createDirectory(directoryPath).then((path) => { console.log(`Successfully created directory: '${path}'`); }).catch((error) => { console.log(`Problem creating directory: ${error.message}`) }); 

Remarque:

  • Au début de la fonction createDirectory , je normalise le chemin pour garantir que le type du séparateur de chemin du système d'exploitation sera utilisé de manière cohérente (par exemple, cela va transformer C:\directory/test en C:\directory\test (lorsqu'il est sur Windows )
  • fs.exists est obsolète , c'est pourquoi j'utilise fs.stat pour vérifier si le répertoire existe déjà
  • Si un répertoire n'existe pas, le code d'erreur sera ENOENT ( E rror NO ENT ry)
  • Le répertoire lui-même sera créé en utilisant fs.mkdir
  • Je préfère la fonction asynchrone fs.mkdir sur le blocage de la contrepartie fs.mkdirSync et en raison de l'emballage. Promise il sera garanti que le chemin du répertoire ne sera renvoyé qu'après la création du répertoire

Je vous recommande plus simple:

 // Get modules node const fs = require('fs'); const path = require('path'); // Create function mkdirpath(dirPath) { if(!fs.existsSync(dirPath)) { try { fs.mkdirSync(dirPath); } catch(e) { mkdirpath(path.dirname(dirPath)); mkdirpath(dirPath); } } } // Create folder path mkdirpath('my/new/folder/create'); 
 var fs = require('fs'); if (fs.existsSync('temp')) { console.log('Directory exists, removing...'); if (fs.existsSync('temp/new.txt')) { fs.unlinkSync('temp/new.txt'); } fs.rmdirSync('temp'); } fs.mkdirSync('temp'); if (fs.existsSync('temp')) { process.chdir('temp'); fs.writeFileSync('test.txt', 'This is some test text for the file'); fs.renameSync('test.txt','new.txt'); console.log('File has size: ' + fs.statSync('new.txt').size + ' bytes'); console.log('File contents: ' + fs.readFileSync('new.txt').toString()); }