risposta-alla-domanda-sullo-sviluppo-web-bd.com

Node.js controlla se il percorso è file o directory

Non riesco a ottenere risultati di ricerca che spieghino come farlo.

Tutto quello che voglio fare è essere in grado di sapere se un determinato percorso è un file o una directory (cartella).

320
ThomasReggi

fs.lstatSync(path_string).isDirectory() dovrebbe dirti. Dal docs :

Gli oggetti restituiti da fs.stat () e fs.lstat () sono di questo tipo.

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

NOTA: la soluzione sopra mostrerà throw an Error if; per esempio, file o directory non esiste. Se vuoi un truthy o falsy prova fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory(); come menzionato da Joseph nei commenti sottostanti.

500
Jason Sperske

Aggiornamento: Node.Js> = 10

Possiamo usare la nuova fs.promises API

Sperimentale Questa funzione è ancora in fase di sviluppo attivo e soggetta a modifiche non retrocompatibili, o addirittura alla rimozione, in qualsiasi versione futura. L'uso della funzione non è raccomandato negli ambienti di produzione. Le funzionalità sperimentali non sono soggette al modello di versione semantica di Node.js.

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

(async() => {

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

Qualsiasi versione di Node.Js

Ecco come si rileva se un percorso è un file o una directory in modo asincrono , che è l'approccio raccomandato nel nodo. using 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()}`);
});

Nota quando si utilizza l'API sincrona:

Quando si utilizza il modulo sincrono vengono lanciate immediatamente tutte le eccezioni. Puoi usare try/catch per gestire le eccezioni o permetterle di creare bolle.

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
   }
}
41

Seriamente, la domanda esiste cinque anni e nessuna facciata di Nizza?

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;
    }
}
11
lama12345

A seconda delle tue esigenze, puoi probabilmente contare sul modulo path del nodo.

Potresti non essere in grado di colpire il filesystem (ad esempio il file non è ancora stato creato) e probabilmente non vuoi colpire il filesystem a meno che tu non abbia davvero bisogno della validazione extra. Se puoi fare l'ipotesi che quello che stai cercando segue il formato .<extname>, guarda il nome.

Ovviamente se stai cercando un file senza un extname dovrai essere sicuro che il file system sia presente. Ma mantienilo semplice finché non avrai bisogno di più complicazioni.

const path = require('path');

function isFile(pathItem) {
  return !!path.extname(pathItem);
}
6
cndw

Le risposte precedenti controllano se un filesystem contiene un percorso che è un file o una directory. Ma non identifica se un solo percorso è un file o una directory.

La risposta è identificare i percorsi basati su directory usando "/." come -> "/ c/dos/run /." <- periodo di trascinamento.

Come un percorso di una directory o di un file che non è stato ancora scritto. O un percorso da un altro computer. O un percorso in cui esiste sia un file che una directory con lo stesso nome.

// /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);
}

Versione del nodo: v11.10.0 - Feb 2019

Ultimo pensiero: perché colpire il filesystem?

1
TamusJRoyce

Ecco una funzione autonoma che uso in alcuni dei miei programmi. Nessuno sta facendo uso della caratteristica promisify e await/async in questo post, quindi ho pensato di condividerlo.

const isDirectory = async path => {
  try {
    return (await require('util').promisify(require('fs').lstat)(path)).isDirectory()
  } catch (e) {
    return false // or custom the error
  }
}

Nota: non uso require('fs').promises; perché è stato sperimentale da un anno a questa parte, piuttosto che non fare affidamento su di esso.

0
vdegenne