Überprüfen Sie synchron, ob Datei / Verzeichnis in Node.js vorhanden ist


1209

Wie kann ich mithilfe von node.js synchron prüfen, ob eine Datei oder ein Verzeichnis vorhanden ist?


58
Synchrone Operationen eignen sich hervorragend zum Ausführen einmaliger Datei- / Verzeichnisoperationen, bevor ein Modul zurückgegeben wird. Beispiel: Bootstrapping einer Konfigurationsdatei.
Jocull

1
@PaulDraper mit einem warmen Cache ist nicht in allen Fällen wahr.
Mikemaccana

12
Unabhängig von der Leistung möchten Sie es manchmal nur synchron ausführen, um die Entwicklererfahrung zu verbessern. Wenn Sie beispielsweise Node für ein Datenverarbeitungsskript verwenden, das standardmäßig blockiert werden soll, existsfügt async in diesem Fall nur unnötige Rückrufe hinzu.
Kunok

3
Auf jeden Fall +1 zu Kunoks Aussage. Im Rest meines Codes mache ich Code nur dann komplexer, wenn es sich um einen Engpass handelt, bei dem die Geschwindigkeit wirklich wichtig ist. Warum sollte ich dieses Prinzip nicht auf das Lesen von Dateien anwenden? In vielen Teilen vieler Programme kann die Einfachheit / Lesbarkeit des Codes wichtiger sein als die Ausführungsgeschwindigkeit. Wenn es sich um einen Engpass handelt, verwende ich asynchrone Methoden, um die weitere Codeausführung nicht zu stoppen. Ansonsten ... ist die Synchronisierung großartig. Hassen Sie Synchronisierung nicht blind.
BryanGrezeszak

3
Bitte ... nicht "erwähnenswert", da der Benutzer explizit fragt, wie es synchron gemacht werden soll.
jClark

Antworten:


2241

Die Antwort auf diese Frage hat sich im Laufe der Jahre geändert. Die aktuelle Antwort befindet sich hier oben, gefolgt von den verschiedenen Antworten im Laufe der Jahre in chronologischer Reihenfolge:

Aktuelle Antwort

Sie können verwenden fs.existsSync():

const fs = require("fs"); // Or `import fs from "fs";` with ESM
if (fs.existsSync(path)) {
    // Do something
}

Es war mehrere Jahre veraltet, ist es aber nicht mehr. Aus den Dokumenten:

Beachten Sie, dass dies fs.exists()veraltet ist, aber fs.existsSync()nicht. (Der Rückrufparameter zum fs.exists()Akzeptieren von Parametern, die nicht mit anderen Node.js-Rückrufen übereinstimmen. fs.existsSync()Verwendet keinen Rückruf.)

Sie haben ausdrücklich um eine synchrone Prüfung gebeten. Wenn Sie jedoch stattdessen eine asynchrone Prüfung verwenden können (normalerweise am besten mit E / A), verwenden fs.promises.accessSie diese , wenn Sie asyncFunktionen verwenden, oder fs.access(da sie existsveraltet ist ), wenn nicht:

In einer asyncFunktion:

try {
    await fs.promises.access("somefile");
    // The check succeeded
} catch (error) {
    // The check failed
}

Oder mit einem Rückruf:

fs.access("somefile", error => {
    if (!error) {
        // The check succeeded
    } else {
        // The check failed
    }
});

Historische Antworten

Hier sind die historischen Antworten in chronologischer Reihenfolge:

  • Ursprüngliche Antwort von 2010
    ( stat/ statSyncoder lstat/ lstatSync)
  • Update September 2012
    ( exists/ existsSync)
  • Update Februar 2015
    (Angesichts der bevorstehenden Abwertung von exists/ existsSyncsind wir wahrscheinlich wieder bei stat/ statSyncoder lstat/ lstatSync)
  • Update Dezember 2015
    (Es gibt auch fs.access(path, fs.F_OK, function(){})/ fs.accessSync(path, fs.F_OK), aber das zur Kenntnis , wenn die Datei / Verzeichnis nicht vorhanden ist , dann ist es ein Fehler, docs für fs.statempfehlen die Verwendung , fs.accesswenn Sie benötigen die Existenz ohne Öffnung zu überprüfen)
  • Das Update Dezember 2016
    fs.exists() ist immer noch veraltet, aber fs.existsSync()nicht mehr veraltet. So können Sie es jetzt sicher verwenden.

Ursprüngliche Antwort von 2010:

Sie können statSyncoder lstatSync( docs link ) verwenden, um ein fs.StatsObjekt zu erhalten . Wenn eine synchrone Version einer Funktion verfügbar ist, hat sie im Allgemeinen denselben Namen wie die asynchrone Version Syncam Ende. So statSyncist die synchrone Version von stat; lstatSyncist die synchrone Version von lstatusw.

lstatSync Hier erfahren Sie sowohl, ob etwas vorhanden ist, als auch, ob es sich um eine Datei oder ein Verzeichnis handelt (oder in einigen Dateisystemen um eine symbolische Verknüpfung, ein Blockgerät, ein Zeichengerät usw.), z. B. ob Sie wissen müssen, ob es vorhanden ist und vorhanden ist ein Verzeichnis:

var fs = require('fs');
try {
    // Query the entry
    stats = fs.lstatSync('/the/path');

    // Is it a directory?
    if (stats.isDirectory()) {
        // Yes it is
    }
}
catch (e) {
    // ...
}

... und ähnlich, wenn es eine Datei ist, gibt es isFile; Wenn es sich um ein Blockgerät handelt, gibt es isBlockDeviceusw. usw. Beachten Sie die try/catch; Es wird ein Fehler ausgegeben, wenn der Eintrag überhaupt nicht vorhanden ist.

Wenn es Ihnen egal ist, was der Eintrag ist, und Sie nur wissen möchten, ob er vorhanden ist, können Sie path.existsSync(oder mit der neuesten Versionfs.existsSync ) Folgendes verwenden , wie von user618408 angegeben :

var path = require('path');
if (path.existsSync("/the/path")) { // or fs.existsSync
    // ...
}

Es erfordert kein try/catch, gibt Ihnen aber keine Informationen darüber, was das Ding ist, nur dass es da ist. path.existsSyncwurde vor langer Zeit veraltet.


Randnotiz: Sie haben ausdrücklich gefragt, wie Sie synchron prüfen sollen , daher habe ich die xyzSyncVersionen der oben genannten Funktionen verwendet. Bei E / A ist es jedoch am besten, synchrone Anrufe zu vermeiden. Anrufe in das E / A-Subsystem nehmen aus Sicht einer CPU viel Zeit in Anspruch. Beachten Sie, wie einfach es ist, anzurufen, lstatanstatt lstatSync:

// Is it a directory?
lstat('/the/path', function(err, stats) {
    if (!err && stats.isDirectory()) {
        // Yes it is
    }
});

Aber wenn Sie die synchrone Version benötigen, ist sie da.

Update September 2012

Die folgende Antwort von vor ein paar Jahren ist jetzt etwas veraltet. Die derzeitige Methode besteht darin fs.existsSync, eine synchrone Prüfung auf Datei- / Verzeichnisexistenz (oder natürlich fs.existseine asynchrone Prüfung) anstelle der folgenden pathVersionen durchzuführen.

Beispiel:

var fs = require('fs');

if (fs.existsSync(path)) {
    // Do something
}

// Or

fs.exists(path, function(exists) {
    if (exists) {
        // Do something
    }
});

Update Februar 2015

Und hier sind wir im Jahr 2015 und die Node-Dokumente sagen jetzt, dass fs.existsSync(und fs.exists) "veraltet sein werden". (Weil die Node-Leute denken, es sei dumm zu prüfen, ob etwas existiert, bevor sie es öffnen, was es ist; aber das ist nicht der einzige Grund, um zu überprüfen, ob etwas existiert!)

Wir sind also wahrscheinlich wieder bei den verschiedenen statMethoden ... Bis sich dies natürlich noch einmal ändert.

Update Dezember 2015

Ich weiß nicht, wie lange es schon da ist, aber es gibt auch fs.access(path, fs.F_OK, ...)/fs.accessSync(path, fs.F_OK) . Zumindest ab Oktober 2016 wird in der fs.statDokumentation empfohlen fs.access, Existenzprüfungen durchzuführen ( "Es fs.access()wird empfohlen, zu überprüfen, ob eine Datei vorhanden ist, ohne sie anschließend zu bearbeiten." ). Beachten Sie jedoch, dass der nicht verfügbare Zugriff als Fehler angesehen wird. Dies ist wahrscheinlich am besten, wenn Sie erwarten, dass auf die Datei zugegriffen werden kann:

var fs = require('fs');

try {
    fs.accessSync(path, fs.F_OK);
    // Do something
} catch (e) {
    // It isn't accessible
}

// Or

fs.access(path, fs.F_OK, function(err) {
    if (!err) {
        // Do something
    } else {
        // It isn't accessible
    }
});

Update Dezember 2016

Sie können verwenden fs.existsSync():

if (fs.existsSync(path)) {
    // Do something
}

Es war mehrere Jahre veraltet, ist es aber nicht mehr. Aus den Dokumenten:

Beachten Sie, dass dies fs.exists()veraltet ist, aber fs.existsSync()nicht. (Der Rückrufparameter zum fs.exists()Akzeptieren von Parametern, die nicht mit anderen Node.js-Rückrufen übereinstimmen. fs.existsSync()Verwendet keinen Rückruf.)


7
path.exists und path.existsSync wurden beide zugunsten von fs.exists und fs.existsSync
Drew

15
"Knotenleute halten es für dumm zu prüfen, ob etwas existiert, bevor sie es öffnen, was es ist." Warum ist es dumm zu überprüfen, ob eine Datei existiert?
Petr Hurtak

32
@PetrHurtak: Es ist nicht immer so (weil es viele Gründe gibt, die Existenz zu überprüfen), aber wenn Sie die Datei öffnen , ist es am besten, einfach den openAufruf auszugeben und die Ausnahme zu behandeln, oder was auch immer, wenn die Datei nicht war gefunden. Schließlich ist die reale Welt chaotisch: Wenn Sie zuerst nachsehen, ob sie da ist, heißt das nicht, dass sie immer noch da ist, wenn Sie versuchen, sie zu öffnen. Wenn Sie zuerst nachsehen und es nicht da ist, heißt das nicht, dass es einen Moment später nicht da sein wird. Timing Dinge wie das scheint wie Grenzfälle, aber sie kommen die ganze Zeit . Also , wenn Sie öffnen gehen, kein Punkt bei der Prüfung zuerst.
TJ Crowder

13
Und hier dachte ich, es sei ein Anti-Muster, Fehler für den Kontrollfluss zu verwenden: link
argyle

4
@ Jeromeyers: Sie könnten, aber Ionică hat es bereits für Sie getan (siehe Kommentar oben ). :-)
TJ Crowder

124

Wenn man sich die Quelle ansieht, gibt es eine synchrone Version von path.exists- path.existsSync. Sieht so aus, als wäre es in den Dokumenten übersehen worden.

Aktualisieren:

path.existsund path.existsSyncsind jetzt veraltet . Bitte benutzen Sie fs.existsundfs.existsSync .

Update 2016:

fs.exists und fs.existsSyncwurden ebenfalls veraltet . Verwenden Sie stattdessen fs.stat () oder fs.access () .

Update 2019:

verwenden fs.existsSync. Es ist nicht veraltet. https://nodejs.org/api/fs.html#fs_fs_existssync_path


1
path.existsSync (p) ist in der 0.4.10 docs nodejs.org/docs/v0.4.10/api/path.html
Paul Beusterien

21
Eigentlich eine neuere Antwort: path.existsSync ist veraltet. Es heißt jetzt fs.existsSync.
Olivier Lalonde

9
Jetzt sagen die Dokumente, dass fs.exists veraltet sein wird. nodejs.org/api/fs.html#fs_fs_existssync_path
Greg Hornby

Ich schrieb eine kleine Bibliothek, um die alte existsFunktion zu ersetzen :is-there
Ionică Bizău

6
aktuelle Dokumente (Version ~ 9) werden nur fs.existsals veraltet gekennzeichnet, solange dies fs.existsSyncnicht der Fall ist!
Kunok

57

Mit den derzeit empfohlenen (ab 2015) APIs (gemäß den Knotendokumenten) mache ich Folgendes:

var fs = require('fs');

function fileExists(filePath)
{
    try
    {
        return fs.statSync(filePath).isFile();
    }
    catch (err)
    {
        return false;
    }
}

Als Antwort auf das von @broadband in den Kommentaren angesprochene EPERM-Problem bringt dies einen guten Punkt hervor. fileExists () ist in vielen Fällen wahrscheinlich keine gute Möglichkeit, darüber nachzudenken, da fileExists () eine boolesche Rückgabe nicht wirklich versprechen kann. Möglicherweise können Sie definitiv feststellen, ob die Datei vorhanden ist oder nicht, aber möglicherweise wird auch ein Berechtigungsfehler angezeigt. Der Berechtigungsfehler bedeutet nicht unbedingt, dass die Datei vorhanden ist, da Ihnen möglicherweise die Berechtigung für das Verzeichnis fehlt, das die Datei enthält, die Sie überprüfen. Und natürlich besteht die Möglichkeit, dass bei der Überprüfung der Dateidexistenz ein anderer Fehler auftritt.

Mein Code oben lautet also wirklich doesFileExistAndDoIHaveAccessToIt (), aber Ihre Frage könnte doesFileNotExistAndCouldICreateIt () sein, was eine völlig andere Logik wäre (die unter anderem einen EPERM-Fehler berücksichtigen müsste).

Während die Antwort von fs.existsSync die hier gestellte Frage direkt anspricht, wird dies oft nicht das sein, was Sie wollen (Sie möchten nicht nur wissen, ob "etwas" auf einem Pfad vorhanden ist, Sie interessieren sich wahrscheinlich dafür, ob das "Ding" das existiert ist eine Datei oder ein Verzeichnis).

Wenn Sie überprüfen, ob eine Datei vorhanden ist, tun Sie dies wahrscheinlich, weil Sie beabsichtigen, basierend auf dem Ergebnis eine Aktion auszuführen, und diese Logik (die Überprüfung und / oder die nachfolgende Aktion) sollte die Idee berücksichtigen dass ein Objekt, das sich in diesem Pfad befindet, eine Datei oder ein Verzeichnis sein kann und dass bei der Überprüfung möglicherweise EPERM oder andere Fehler auftreten.


4
Schön, habe ich hinzugefügt || isDirectory (), um es zu einer Datei- / Ordnerprüfung zu machen. var stats = fs.statSync (filePath); return stats.isFile () || stats.isDirectory ();
Bob

4
Wenn das Programm keine Zugriffsrechte auf die Datei hat, wird immer noch false zurückgegeben, obwohl die Datei vorhanden ist, dh alle Rigts aus der Datei chmod ugo-rwx file.txt oder in Windows entfernen. Rechtsklick ... Ausnahmemeldung: Ausnahme fs.statSync (./ f.txt): Fehler: EPERM: Operation nicht erlaubt, stat 'X: \ f.txt'. Dieser Fall wird also nicht durch den oberen Code abgedeckt.
Breitband

2
Wow, JS ist manchmal zurückgeblieben. Also sicher, 97% der Zeit werden Sie die Datei verwenden, aber keinen einfachen file.exists()Nutzen für die 3% haben und uns stattdessen zwingen, dies in einen Try-Catch zu packen? Werden Sie echt ... Schlampe des Tages.
vertriebener

20

Ein weiteres Update

Ich brauchte selbst eine Antwort auf diese Frage. Ich habe die Knotendokumente nachgeschlagen. Anscheinend sollten Sie nicht fs.exists verwenden, sondern fs.open verwenden und den ausgegebenen Fehler verwenden, um festzustellen, ob eine Datei nicht vorhanden ist:

aus den Dokumenten:

fs.exists () ist ein Anachronismus und existiert nur aus historischen Gründen. Es sollte fast nie einen Grund geben, es in Ihrem eigenen Code zu verwenden.

Insbesondere die Überprüfung, ob eine Datei vor dem Öffnen vorhanden ist, ist ein Anti-Pattern, das Sie für Race-Bedingungen anfällig macht: Ein anderer Prozess kann die Datei zwischen den Aufrufen von fs.exists () und fs.open () entfernen. Öffnen Sie einfach die Datei und behandeln Sie den Fehler, wenn er nicht vorhanden ist.

http://nodejs.org/api/fs.html#fs_fs_exists_path_callback


1
Gibt es eine Möglichkeit, dies mit openSync zu tun, anstatt mit open
Greg Hornby

1
@ GregHornby Ich stelle mir vor, es sollte genauso funktionieren mit openSync
Melbourne2991

2
Für diejenigen, die noch brauchen exists und existsSyncich geschaffen habe is-there.
Ionică Bizău

6
Diese Abwertung nervt mich. Das Öffnen einer Datei, nur um zu sehen, ob ein Fehler ausgelöst wird oder nicht, scheint eine Verschwendung von Ressourcen zu sein, wenn nur die Kenntnis der Existenz der Datei erforderlich ist.
Josh Hansen

11

Ich benutze die folgende Funktion, um zu testen, ob eine Datei existiert. Es werden auch andere Ausnahmen erfasst. Falls es also Rechteprobleme gibt, z. B. chmod ugo-rwx filenameoder in der Windows- Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..Funktion, wird die Ausnahme wie gewünscht zurückgegeben. Die Datei ist vorhanden, wir haben jedoch keine Zugriffsrechte. Es wäre falsch, solche Ausnahmen zu ignorieren.

function fileExists(path) {

  try  {
    return fs.statSync(path).isFile();
  }
  catch (e) {

    if (e.code == 'ENOENT') { // no such file or directory. File really does not exist
      console.log("File does not exist.");
      return false;
    }

    console.log("Exception fs.statSync (" + path + "): " + e);
    throw e; // something else went wrong, we don't have rights, ...
  }
}

Ausnahmeausgabe, NodeJS-Fehlerdokumentation für den Fall, dass keine Datei vorhanden ist:

{
  [Error: ENOENT: no such file or directory, stat 'X:\\delsdfsdf.txt']
  errno: -4058,
  code: 'ENOENT',
  syscall: 'stat',
  path: 'X:\\delsdfsdf.txt'
}

Ausnahme für den Fall, dass wir keine Rechte an der Datei haben, aber vorhanden sind:

{
  [Error: EPERM: operation not permitted, stat 'X:\file.txt']
  errno: -4048,
  code: 'EPERM',
  syscall: 'stat',
  path: 'X:\\file.txt'
}

2
Wirklich so, es ist eine der wenigen Antworten, die auf dem neuesten Stand ist, da Node die letzten 37 Möglichkeiten, dies zu tun,
abgelehnt hat

Bah, du hast mich geschlagen. Ich hätte etwas Zeit sparen können, wenn ich das gelesen hätte.
jgmjgm

5

fs.exists () ist veraltet. Verwenden Sie es nicht https://nodejs.org/api/fs.html#fs_fs_exists_path_callback

Sie können die hier verwendete Methode für den Kernknoten implementieren: https://github.com/nodejs/node-v0.x-archive/blob/master/lib/module.js#L86

function statPath(path) {
  try {
    return fs.statSync(path);
  } catch (ex) {}
  return false;
}

Dadurch wird das Statistikobjekt zurückgegeben. Sobald Sie das Statistikobjekt haben, können Sie es versuchen

var exist = statPath('/path/to/your/file.js');
if(exist && exist.isFile()) {
  // do something
}

4

Einige Antworten hier sagen das fs.existsund fs.existsSyncsind beide veraltet. Laut den Dokumenten ist dies nicht mehr wahr. Nur fs.existsist jetzt veraltet:

Beachten Sie, dass fs.exists () veraltet ist, fs.existsSync () jedoch nicht. (Der Rückrufparameter für fs.exists () akzeptiert Parameter, die nicht mit anderen Node.js-Rückrufen übereinstimmen. Fs.existsSync () verwendet keinen Rückruf.)

Sie können also sicher mit fs.existsSync () synchron prüfen, ob eine Datei vorhanden ist.


3

Das pathModul bietet keine synchrone Version von, path.existssodass Sie mit dem fsModul herumspielen müssen.

Das Schnellste, was ich mir vorstellen kann, ist die Verwendung fs.realpathSynceines Fehlers, den Sie abfangen müssen. Sie müssen also Ihre eigene Wrapper-Funktion mit einem Versuch / Fang erstellen.


1

Die Verwendung von fileSystem (fs) -Tests löst Fehlerobjekte aus, die Sie dann in eine try / catch-Anweisung einschließen müssten. Sparen Sie sich Mühe und verwenden Sie eine Funktion, die im Zweig 0.4.x eingeführt wurde.

var path = require('path');

var dirs = ['one', 'two', 'three'];

dirs.map(function(dir) {
  path.exists(dir, function(exists) {
    var message = (exists) ? dir + ': is a directory' : dir + ': is not a directory';
    console.log(message);
  });
});

2
Die path.exists ist jetzt unter fs, also ist es fs.exists (Pfad, Rückruf)
Todd Moses

0

Die Dokumente auf fs.stat()sagt zu verwendenfs.access() wenn die Datei nicht bearbeitet werden soll. Es gab keine Rechtfertigung, könnte schneller oder weniger Speicher verwendet werden?

Ich verwende Node für die lineare Automatisierung, daher dachte ich, ich teile die Funktion, mit der ich die Existenz von Dateien teste.

var fs = require("fs");

function exists(path){
    //Remember file access time will slow your program.
    try{
        fs.accessSync(path);
    } catch (err){
        return false;
    }
    return true;
}

0

aktualisiert asnwer für jene Leute 'richtig', die darauf hinweisen, dass es die Frage nicht direkt beantwortet, mehr bringen eine alternative Option.

Synchronisierungslösung:

fs.existsSync('filePath')auch hier sehen docs .

Gibt true zurück, wenn der Pfad vorhanden ist, andernfalls false.

Async Promise-Lösung

In einem asynchronen Kontext können Sie die asynchrone Version einfach synchron mit dem awaitSchlüsselwort schreiben . Sie können die asynchrone Rückrufmethode einfach in ein Versprechen wie das folgende umwandeln:

function fileExists(path){
  return new Promise((resolve, fail) => fs.access(path, fs.constants.F_OK, 
    (err, result) => err ? fail(err) : resolve(result))
  //F_OK checks if file is visible, is default does no need to be specified.

}

async function doSomething() {
  var exists = await fileExists('filePath');
  if(exists){ 
    console.log('file exists');
  }
}

die Dokumente bei access ().


1
Das OP will eine synchrone Lösung
vdegenne

Sie sollten Ihren Code auffunction asyncFileExists(path) { //F_OK checks if file is visible, is default does no need to be specified. return new Promise(function (res, rej) { fs.access( path, fs.constants.F_OK, function (err) { err ? rej(err) : res(true); }, ); }); }
pery mimon

0

Wenn Sie wissen möchten, ob eine Datei vorhanden ist, möchten Sie diese möglicherweise anfordern, wenn dies der Fall ist.

function getFile(path){
    try{
        return require(path);
    }catch(e){
        return false;
    }
}

-1

Hier ist eine einfache Wrapper-Lösung dafür:

var fs = require('fs')
function getFileRealPath(s){
    try {return fs.realpathSync(s);} catch(e){return false;}
}

Verwendungszweck:

  • Funktioniert sowohl für Verzeichnisse als auch für Dateien
  • Wenn ein Element vorhanden ist, wird der Pfad zur Datei oder zum Verzeichnis zurückgegeben
  • Wenn das Element nicht vorhanden ist, wird false zurückgegeben

Beispiel:

var realPath,pathToCheck='<your_dir_or_file>'
if( (realPath=getFileRealPath(pathToCheck)) === false){
    console.log('file/dir not found: '+pathToCheck);
} else {
    console.log('file/dir exists: '+realPath);
}

Stellen Sie sicher, dass Sie den Operator === verwenden, um zu testen, ob return gleich false ist. Es gibt keinen logischen Grund, warum fs.realpathSync () unter geeigneten Arbeitsbedingungen false zurückgeben würde, daher denke ich, dass dies zu 100% funktionieren sollte.

Ich würde es vorziehen, eine Lösung zu sehen, die keinen Fehler und keinen daraus resultierenden Leistungseinbruch erzeugt. Aus API-Sicht scheint fs.exists () die eleganteste Lösung zu sein.


1
@ Dan, danke. Ich habe den abgeschnittenen Text entfernt. Ich kann mich nicht erinnern, was die Notiz war. Wenn es mir kommt, werde ich Notizen hinzufügen.
Timothy C. Quinn

1
Np. Ich lösche meinen Kommentar.
Dan Dascalescu

-2

Aus den Antworten geht hervor, dass es hierfür keine offizielle API-Unterstützung gibt (wie bei einer direkten und expliziten Überprüfung). Viele der Antworten sagen, dass stat verwendet werden soll, sie sind jedoch nicht streng. Wir können zum Beispiel nicht davon ausgehen, dass ein von stat ausgelöster Fehler bedeutet, dass etwas nicht existiert.

Nehmen wir an, wir versuchen es mit etwas, das es nicht gibt:

$ node -e 'require("fs").stat("god",err=>console.log(err))'
{ Error: ENOENT: no such file or directory, stat 'god' errno: -2, code: 'ENOENT', syscall: 'stat', path: 'god' }

Versuchen wir es mit etwas, das existiert, auf das wir aber keinen Zugriff haben:

$ mkdir -p fsm/appendage && sudo chmod 0 fsm
$ node -e 'require("fs").stat("fsm/appendage",err=>console.log(err))'
{ Error: EACCES: permission denied, stat 'access/access' errno: -13, code: 'EACCES', syscall: 'stat', path: 'fsm/appendage' }

Zumindest wollen Sie:

let dir_exists = async path => {
    let stat;
    try {
       stat = await (new Promise(
           (resolve, reject) => require('fs').stat(path,
               (err, result) => err ? reject(err) : resolve(result))
       ));
    }
    catch(e) {
        if(e.code === 'ENOENT') return false;
        throw e;
    }

    if(!stat.isDirectory())
        throw new Error('Not a directory.');

    return true;
};

Die Frage ist nicht klar, ob es tatsächlich synchron sein soll oder ob es nur so geschrieben werden soll, als ob es synchron wäre. In diesem Beispiel wird await / async verwendet, sodass es nur synchron geschrieben wird, aber asynchron ausgeführt wird.

Dies bedeutet, dass Sie es auf der obersten Ebene als solches bezeichnen müssen:

(async () => {
    try {
        console.log(await dir_exists('god'));
        console.log(await dir_exists('fsm/appendage'));
    }
    catch(e) {
        console.log(e);
    }
})();

Eine Alternative ist die Verwendung von .then und .catch für das vom asynchronen Aufruf zurückgegebene Versprechen, wenn Sie es weiter unten benötigen.

Wenn Sie überprüfen möchten, ob etwas vorhanden ist, sollten Sie auch sicherstellen, dass es sich um die richtige Art von Dingen handelt, z. B. ein Verzeichnis oder eine Datei. Dies ist im Beispiel enthalten. Wenn es kein Symlink sein darf, müssen Sie lstat anstelle von stat verwenden, da stat automatisch Links durchläuft.

Sie können hier den gesamten asynchronen Code für die Synchronisierung ersetzen und stattdessen statSync verwenden. Erwarten Sie jedoch, dass die Synchronisierungsaufrufe, sobald Async und Warten allgemein unterstützt werden, überflüssig werden und schließlich abgeschrieben werden (andernfalls müssten Sie sie überall und in der Kette definieren, genau wie bei Async, was es wirklich sinnlos macht).


1
Die ursprüngliche Frage spezifiziert das nicht. Ich zeige auch, wie man Dinge eindeutig macht. Viele Antworten können aufgrund mangelnder Klarheit zu Fehlern führen. Die Leute wollen oft Dinge so programmieren, dass sie synchron erscheinen, wollen aber nicht unbedingt eine synchrone Ausführung. statSync ist nicht dasselbe wie der Code, den ich demonstriert habe. Beide Berichte darüber, was tatsächlich gewünscht wird, sind nicht eindeutig, sodass Sie nur Ihre persönlichen Interpretationen auferlegen. Wenn Sie eine Antwort finden, die Sie nicht verstehen, ist es möglicherweise besser, einfach in den Kommentaren oder in der PM nachzufragen, welche Änderungen erforderlich sind.
jgmjgm

1
Wenn Sie möchten, können Sie auch mein Codebeispiel stehlen, es entsprechend benennen, auf github setzen, es zu npm hinzufügen und dann wird die Antwort nur eine Zeile / ein Link sein: D.
jgmjgm

Der Code ist zum Beispiel kurz, aber Sie können gerne einen Bearbeitungsvorschlag einreichen, um &&! IsFile einzuschließen, oder eine Überprüfung auf Symlinks usw. durchführen (auch wenn die Frage niemals explizit angibt, dass dies genau das ist, was sie wollen). Wie ich bereits ausgeführt habe, erfüllt meine Antwort eine Interpretation der Frage und macht nicht dasselbe wie Ihr einzeiliger Vorschlag.
jgmjgm
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.