Node.js sprawdź, czy ścieżka to plik czy katalog

379

Nie mogę uzyskać wyników wyszukiwania, które wyjaśniają, jak to zrobić.

Chcę tylko wiedzieć, czy dana ścieżka jest plikiem, czy katalogiem (folderem).

ThomasReggi
źródło

Odpowiedzi:

609

fs.lstatSync(path_string).isDirectory()powinienem ci powiedzieć. Z dokumentów :

Obiekty zwrócone z fs.stat () i fs.lstat () są tego typu.

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

UWAGA:

Powyższy roztwór będzie if; na przykład, lubthrowErrorfiledirectory nie istnieje.

Jeśli chcesz truelub falsepodejdź, spróbuj, fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();jak wspomniano w komentarzach Josepha.

Jason Sperske
źródło
18
Pamiętaj, że wersja asynchroniczna jest zwykle lepsza, jeśli zależy Ci na ogólnej wydajności aplikacji.
AlexMA
45
Pamiętaj, że jeśli katalog lub plik nie istnieje, otrzymasz błąd z powrotem.
Ethan Mick,
9
let isDirExists = fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
Jossef Harush
Należy pamiętać, że jeśli plik lub katalog nie istnieje, wygeneruje wyjątek, który należy przechwycić, w przeciwnym razie spowoduje nieprawidłowe wyjście.
Sergey Kuznetsov,
59

Aktualizacja: Node.Js> = 10

Możemy użyć nowego API fs.promises

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

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

Dowolna wersja Node.Js

Oto, jak można wykryć, czy ścieżka jest plikiem lub katalogiem asynchronicznie , co jest zalecanym podejściem w węźle. 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()}`);
});

Uwaga podczas korzystania z synchronicznego interfejsu API:

Podczas korzystania z formularza synchronicznego natychmiast zgłaszane są wyjątki. Możesz użyć try / catch, aby obsłużyć wyjątki lub pozwolić im się rozwinąć.

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
źródło
Czy nadal uważa się to za eksperymentalne od marca 2020 r.? Gdzie możemy zobaczyć? - Ups, widzę po kliknięciu powyższego linku, że jest on teraz stabilny (co oznacza, że ​​nie jest już eksperymentalny).
alfreema
20

Poważnie, pytanie istnieje pięć lat i nie ma ładnej fasady?

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
źródło
14

W zależności od potrzeb możesz prawdopodobnie polegać na węzłach path module .

Możesz nie być w stanie trafić do systemu plików (np. Plik nie został jeszcze utworzony) i tbh prawdopodobnie chcesz uniknąć uderzenia w system plików, chyba że naprawdę potrzebujesz dodatkowej weryfikacji. Jeśli możesz założyć, że to, co sprawdzasz, ma .<extname>format, po prostu spójrz na nazwę.

Oczywiście, jeśli szukasz pliku bez nazwy pliku, musisz trafić do systemu plików, aby się upewnić. Ale zachowaj prostotę, dopóki nie będziesz potrzebować bardziej skomplikowanych.

const path = require('path');

function isFile(pathItem) {
  return !!path.extname(pathItem);
}
cndw
źródło
2
Oczywiście to nie zadziała we wszystkich sytuacjach, ale jest o wiele szybsze i łatwiejsze niż inne odpowiedzi, jeśli możesz dokonać niezbędnych założeń.
electrovir
1

Powyższe odpowiedzi sprawdzają, czy system plików zawiera ścieżkę, która jest plikiem lub katalogiem. Ale nie identyfikuje, czy sama ścieżka jest plikiem czy katalogiem.

Odpowiedzią jest identyfikacja ścieżek opartych na katalogu za pomocą „/”. jak -> "/ c / dos / run /." <- końcowy okres.

Jak ścieżka do katalogu lub pliku, który nie został jeszcze zapisany. Lub ścieżka z innego komputera. Lub ścieżka, w której istnieje zarówno plik, jak i katalog o tej samej nazwie.

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

Wersja węzła: v11.10.0 - luty 2019

Ostatnia myśl: dlaczego w ogóle uderzyć w system plików?

TamusJRoyce
źródło
1

Oto funkcja, której używam. Nikt nie jest wykorzystanie promisifyi await/asyncfunkcji w tym poście więc pomyślałem, że podzielę.

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

Uwaga: nie używam, require('fs').promises;ponieważ jest eksperymentalny od roku, lepiej nie polegaj na nim.

Vdegenne
źródło