Node.js vérifie si le chemin est un fichier ou un répertoire

381

Je n'arrive pas à obtenir de résultats de recherche expliquant comment procéder.

Tout ce que je veux faire, c'est savoir si un chemin donné est un fichier ou un répertoire (dossier).

ThomasReggi
la source

Réponses:

610

fs.lstatSync(path_string).isDirectory()devrait vous dire. De la documentation :

Les objets renvoyés par fs.stat () et fs.lstat () sont de ce type.

stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() (only valid with fs.lstat())
stats.isFIFO()
stats.isSocket()

REMARQUE:

La solution ci-dessus sera throwun Errorif; par exemple, le fileou directoryn'existe pas.

Si vous voulez une approche trueou false, essayez fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();comme mentionné par Joseph dans les commentaires ci-dessous.

Jason Sperske
la source
18
Notez que la version asynchrone est généralement préférable si vous vous souciez des performances générales de l'application.
AlexMA
45
Gardez à l'esprit que si le répertoire ou le fichier n'existe pas, vous obtiendrez alors une erreur.
Ethan Mick
9
let isDirExists = fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
Jossef Harush
Gardez à l'esprit que si le fichier ou le répertoire n'existe pas, il lèvera une exception qui doit être interceptée, sinon cela entraînera une sortie anormale.
Sergey Kuznetsov
59

Mise à jour: Node.Js> = 10

Nous pouvons utiliser la nouvelle API fs.promises

const fs = require('fs').promises;

(async() => {
    const stat = await fs.lstat('test.txt');
    console.log(stat.isFile());
})().catch(console.error)

Toute version de Node.Js

Voici comment vous pourriez détecter si un chemin est un fichier ou un répertoire de manière asynchrone , ce qui est l'approche recommandée dans le nœud. en utilisant fs.lstat

const fs = require("fs");

let path = "/path/to/something";

fs.lstat(path, (err, stats) => {

    if(err)
        return console.log(err); //Handle error

    console.log(`Is file: ${stats.isFile()}`);
    console.log(`Is directory: ${stats.isDirectory()}`);
    console.log(`Is symbolic link: ${stats.isSymbolicLink()}`);
    console.log(`Is FIFO: ${stats.isFIFO()}`);
    console.log(`Is socket: ${stats.isSocket()}`);
    console.log(`Is character device: ${stats.isCharacterDevice()}`);
    console.log(`Is block device: ${stats.isBlockDevice()}`);
});

Remarque lors de l'utilisation de l'API synchrone:

Lors de l'utilisation du formulaire synchrone, toutes les exceptions sont immédiatement levées. Vous pouvez utiliser try / catch pour gérer les exceptions ou leur permettre de bouillonner.

try{
     fs.lstatSync("/some/path").isDirectory()
}catch(e){
   // Handle error
   if(e.code == 'ENOENT'){
     //no such file or directory
     //do something
   }else {
     //do something else
   }
}
Marcos Casagrande
la source
Est-ce encore considéré comme expérimental en mars 2020? Où pouvons-nous regarder pour voir? - Oups, je vois quand je clique sur le lien ci-dessus qu'il est désormais stable (ce qui implique qu'il n'est plus expérimental).
alfreema
20

Sérieusement, la question existe depuis cinq ans et pas de belle façade?

function is_dir(path) {
    try {
        var stat = fs.lstatSync(path);
        return stat.isDirectory();
    } catch (e) {
        // lstatSync throws an error if path doesn't exist
        return false;
    }
}
lama12345
la source
14

Selon vos besoins, vous pouvez probablement compter sur le pathmodule du nœud .

Vous ne pourrez peut-être pas toucher le système de fichiers (par exemple, le fichier n'a pas encore été créé) et tbh vous voudrez probablement éviter de frapper le système de fichiers à moins d'avoir vraiment besoin de la validation supplémentaire. Si vous pouvez faire l'hypothèse que ce que vous recherchez respecte le .<extname>format, regardez simplement le nom.

Évidemment, si vous recherchez un fichier sans nom extensible, vous devrez frapper le système de fichiers pour être sûr. Mais restez simple jusqu'à ce que vous ayez besoin de plus de complication.

const path = require('path');

function isFile(pathItem) {
  return !!path.extname(pathItem);
}
cndw
la source
2
Évidemment, cela ne fonctionnera pas dans toutes les situations, mais c'est beaucoup plus rapide et plus facile que les autres réponses si vous pouvez faire les hypothèses nécessaires.
electrovir
1

Les réponses ci-dessus vérifient si un système de fichiers contient un chemin d'accès qui est un fichier ou un répertoire. Mais il n'identifie pas si un chemin donné seul est un fichier ou un répertoire.

La réponse est d'identifier les chemins basés sur les répertoires à l'aide de "/". comme -> "/ c / dos / run /." <- période de fuite.

Comme le chemin d'un répertoire ou d'un fichier qui n'a pas encore été écrit. Ou un chemin depuis un autre ordinateur. Ou un chemin où existent à la fois un fichier et un répertoire du même nom.

// /tmp/
// |- dozen.path
// |- dozen.path/.
//    |- eggs.txt
//
// "/tmp/dozen.path" !== "/tmp/dozen.path/"
//
// Very few fs allow this. But still. Don't trust the filesystem alone!

// Converts the non-standard "path-ends-in-slash" to the standard "path-is-identified-by current "." or previous ".." directory symbol.
function tryGetPath(pathItem) {
    const isPosix = pathItem.includes("/");
    if ((isPosix && pathItem.endsWith("/")) ||
        (!isPosix && pathItem.endsWith("\\"))) {
        pathItem = pathItem + ".";
    }
    return pathItem;
}
// If a path ends with a current directory identifier, it is a path! /c/dos/run/. and c:\dos\run\.
function isDirectory(pathItem) {
    const isPosix = pathItem.includes("/");
    if (pathItem === "." || pathItem ==- "..") {
        pathItem = (isPosix ? "./" : ".\\") + pathItem;
    }
    return (isPosix ? pathItem.endsWith("/.") || pathItem.endsWith("/..") : pathItem.endsWith("\\.") || pathItem.endsWith("\\.."));
} 
// If a path is not a directory, and it isn't empty, it must be a file
function isFile(pathItem) {
    if (pathItem === "") {
        return false;
    }
    return !isDirectory(pathItem);
}

Version du nœud: v11.10.0 - février 2019

Dernière pensée: pourquoi même frapper le système de fichiers?

TamusJRoyce
la source
1

Voici une fonction que j'utilise. Personne n'utilise promisifyet ne await/asyncfigure dans ce post, j'ai donc pensé partager.

const promisify = require('util').promisify;
const lstat = promisify(require('fs').lstat);

async function isDirectory (path) {
  try {
    return (await lstat(path)).isDirectory();
  }
  catch (e) {
    return false;
  }
}

Remarque: je ne l'utilise pas require('fs').promises;car il est expérimental depuis un an maintenant, il vaut mieux ne pas s'y fier.

vdegenne
la source