233 votes

Node.js créer un dossier ou utiliser celui existant

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

Actuellement, j'ai ce code, qui essaie de créer un dossier ou d'utiliser un dossier 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 procéder ? Est-ce que la vérification du code EEXIST le bon moyen de savoir que le dossier existe déjà ? Je sais que je peux faire fs.stat() avant de créer le répertoire, mais cela ferait déjà deux accès au système de fichiers.

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

33 votes

Petit détail, mais débarrassez-vous des e && . Si !e échoue, alors vous savez e est véridique.

277voto

Christophe Marois Points 705

Utilisation d'un try {} catch {} vous pouvez y parvenir de manière très élégante sans rencontrer de situation de concurrence :

Tolérant aux pannes fs.mkdirSync(path)

var mkdirSync = function (path) {
  try {
    fs.mkdirSync(path);
  } catch(e) {
    if ( e.code != 'EEXIST' ) throw e;
  }
}

Explication

Dans les deux versions de la fonction, Node essaiera de créer le répertoire et lancera une exception s'il rencontre une exception en le faisant. Dans la version catch {} cependant, nous continuons l'exécution du script comme si rien ne s'était passé si le code d'erreur est EEXIST ce qui signifie que le répertoire existe. Si le code d'erreur n'est pas EEXIST cependant, nous devrions lancer une erreur, car nous avons probablement affaire à une exception de système de fichiers telle que EACCES (permission refusée).

Exemples

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

var fs    = require('fs')
  , path  = require('path');

var mkdirSync = function (path) {
  try {
    fs.mkdirSync(path);
  } catch(e) {
    if ( e.code != 'EEXIST' ) throw e;
  }
}

Méthode 1 : Linéaire

mkdirSync( path.join('first') );
mkdirSync( path.join('first', 'second') );
mkdirSync( path.join('first', 'second', 'third') );
mkdirSync( path.join('first', 'second') ); // Just to demonstrate fault tolerance
mkdirSync( path.join('first', 'second', 'fourth') );

Méthode 2 : mkdir -p -récursion de type

var mkdirpSync = function (dirpath) {
  var parts = dirpath.split(path.sep);
  for( var i = 1; i <= parts.length; i++ ) {
    fs.mkdirSync( path.join.apply(null, parts.slice(0, i)) );
  }
}

mkdirpSync('first/second/third');
mkdirpSync('first/second/fourth');

0 votes

Var fs = Npm.require('fs') ; var dir = process.env.PWD + '/files/users/' + this.userId + '/' ; try { fs.mkdirSync(dir) ; } catch (e) { if (e.code != 'EEXIST') throw e ; }

0 votes

J'ai essayé votre code, créer un js-script qui utilise la création du catalogue comme ceci : mkdirpSync(path.join(__dirname, 'first', 'second', 'third', 'ololol', 'works')) ; Mais j'ai eu cette erreur : $ node 1.js fs.js:747 return binding.mkdir(pathModule._makeLong(path), ^ Error : EPERM, operation not permitted 'C:\' at Error (native) at Object.fs.mkdirSync (fs.js:747:18) at mkdirpSync ( C:\Users\MAXIM\Desktop\test\1.js :15:8) à Objet.<anonyme> ( C:\Users\MAXIM\Desktop\test\1.js :19:1) ... Pouvez-vous me suggérer ce qui ne va pas ? Utilisé sous Windows évidemment :)

0 votes

EPERM semble être un problème de permission, donc le script aurait de toute façon interrompu l'exécution.

244voto

Teemu Ikonen Points 3013

Un bon moyen de le faire est d'utiliser mkdirp module.

$ npm install mkdirp

Ensuite, utilisez-le pour exécuter la fonction qui nécessite le répertoire. Le callback est appelé après la création du chemin (s'il n'existe pas déjà). Une erreur est affichée si mkdirp n'a pas réussi à créer le répertoire path.

var mkdirp = require('mkdirp');
mkdirp('/tmp/some/path/foo', function(err) { 

    // path was created unless there was error

});

6 votes

Il me semble que la réponse correcte (lisez "sans ajout de dépendance") serait celle donnée plus bas, par @Raugaral, qui utilise les éléments suivants fs.exists(Sync) .

0 votes

@meawoppl, c'est 'makedirectory'p. Le 'p' est inconnu.

5 votes

@RicardoPedroni La bonne méthode consiste à utiliser un module. Les modules essaient généralement de résoudre un seul problème, et sont souvent maintenus. Vous pouvez les mettre à jour facilement avec npm. En outre, vous devriez éviter d'utiliser fs.exists[Sync] car son utilisation implique des conditions de course.

27voto

JohnnyHK Points 61191

La documentation de node.js pour fs.mkdir il faut s'en remettre à la page de manuel de Linux pour mkdir(2) . Cela indique que EEXIST sera également indiqué si le chemin existe mais n'est pas un répertoire, ce qui crée un cas de figure gênant si vous suivez cette voie.

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

Ces fs Les méthodes des modules sont des enveloppes minces autour des API C natives. Vous devez donc consulter les pages de manuel référencées dans la documentation de node.js pour plus de détails.

20 votes

Appel à stat avant mkdir a le potentiel pour une condition de course - gardez cela à l'esprit.

26voto

Raugaral Points 111

Vous pouvez utiliser ceci :

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

1 votes

-1. Je ne crois pas que cela fonctionne, statSync lancera une erreur si l'entité n'existe pas du tout, ce qui fera planter le code. Vous devez envelopper cela dans un try/catch bloc.

2 votes

Désolé, je me suis trompé. Remplacez "statSync" par "existsSync".

5 votes

Selon nodejs.org/api/fs.html#fs_fs_mkdirsync_path_mode la variante Sync de mkdir n'accepte pas de callback

3voto

cwyang Points 341

À mon avis, il vaut mieux ne pas compter les hits du système de fichiers pendant que vous codez en Javascript. Cependant, (1) stat & mkdir et (2) mkdir et vérifier (ou rejeter) le code d'erreur, les deux méthodes sont les bonnes pour faire ce que vous voulez.

Merci.

1 votes

C'est un bon moyen de mkdir un répertoire ou d'utiliser un répertoire existant. Je ne vois pas pourquoi vous ne voyez pas. Vérifier le code d'erreur est une bonne chose, alors que rejeter le code d'erreur est juste une bonne chose, n'est-ce pas ?

1 votes

Je vois ce que vous voulez dire. Cependant, je crois qu'il existe de nombreuses façons de faire les choses correctement. Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X