it-swarm.com.de

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

Wie kann ich mit node.js synchron prüfen, ob eine Datei oder ein Verzeichnis existiert?

1071
Ragnis

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 über die Jahre in chronologischer Reihenfolge:

Aktuelle Antwort

Sie können fs.existsSync() verwenden:

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

Es wurde für mehrere Jahre veraltet, ist aber nicht mehr. Aus den Dokumenten:

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 haben speziell nach einer synchronen Prüfung gefragt, aber wenn Sie stattdessen eine asynchrone Prüfung verwenden können (normalerweise am besten mit E/A) ), verwenden Sie fs.promises.access , wenn Sie async-Funktionen verwenden, oder fs.access (da exists veraltet ist ), wenn nicht :

In einer async -Funktion:

_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:

  • Originalantwort von 2010
    (stat/statSync oder lstat/lstatSync)
  • Update September 2012
    (exists/existsSync)
  • Update Februar 2015
    (In Anbetracht der bevorstehenden Abwertung von exists/existsSync sind wir wahrscheinlich wieder bei stat/statSync oder lstat/lstatSync)
  • Update Dezember 2015
    (Es gibt auch fs.access(path, fs.F_OK, function(){})/fs.accessSync(path, fs.F_OK). Beachten Sie jedoch, dass es sich um einen Fehler handelt, wenn die Datei/das Verzeichnis nicht vorhanden ist. In docs for _fs.stat_ wird empfohlen, _fs.access_ zu verwenden, wenn Sie nach Existenz suchen müssen ohne öffnung)
  • Update Dezember 2016
    fs.exists() ist immer noch veraltet, aber fs.existsSync() ist nicht mehr veraltet. So können Sie es jetzt sicher verwenden.

Ursprüngliche Antwort von 2010:

Sie können statSync oder lstatSync ( docs link ) verwenden, wodurch Sie ein _fs.Stats_ -Objekt erhalten. Wenn eine synchrone Version einer Funktion verfügbar ist, hat diese im Allgemeinen denselben Namen wie die asynchrone Version mit Sync am Ende. statSync ist also die synchrone Version von stat; lstatSync ist die synchrone Version von lstat usw.

lstatSync gibt an, ob etwas vorhanden ist, und wenn ja, ob es sich um eine Datei oder ein Verzeichnis handelt (oder in einigen Dateisystemen um eine symbolische Verknüpfung, ein Blockiergerät, ein Zeichengerät usw.), z. Wenn Sie wissen möchten, ob es existiert und ein Verzeichnis ist:

_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 isBlockDevice usw. usw. Beachten Sie den _try/catch_; Es wird ein Fehler ausgegeben, wenn der Eintrag überhaupt nicht vorhanden ist.

Wenn es Ihnen egal ist, wie der Eintrag lautet und Sie nur wissen möchten, ob er existiert, können Sie path.existsSync (oder mit latest verwenden , _fs.existsSync_) as notiert von user618408 :

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

Es erfordert keinen _try/catch_, gibt aber keine Auskunft darüber, was das Ding ist, nur dass es da ist. _path.existsSync_ wurde vor langer Zeit abgelehnt.


Randnotiz: Sie haben ausdrücklich gefragt, wie synchron geprüft werden soll, deshalb habe ich die xyzSync-Versionen der obigen Funktionen verwendet. Aber wo immer möglich, ist es bei E/A am besten, synchrone Anrufe zu vermeiden. Aufrufe in das E/A-Subsystem benötigen aus Sicht der CPU viel Zeit. Beachten Sie, wie einfach es ist, lstat anstelle von lstatSync aufzurufen:

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

Aber wenn Sie die synchrone Version brauchen, ist sie da.

Update September 2012

Die unten stehende Antwort von vor ein paar Jahren ist jetzt etwas veraltet. Der aktuelle Weg ist, fs.existsSync zu verwenden, um eine synchrone Prüfung auf Datei-/Verzeichnisexistenz durchzuführen (oder natürlich fs.exists für eine asynchrone Prüfung), eher als die path Versionen unten.

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 nun, dass _fs.existsSync_ (und _fs.exists_) "veraltet sein werden". (Weil die Leute von Node 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 prüfen, ob etwas existiert!)

Wir kehren also wahrscheinlich zu den verschiedenen stat-Methoden zurück ... Bis/bis sich dies natürlich noch einmal ändert.

Update Dezember 2015

Ich weiß nicht, wie lange es schon 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.stat_ -Dokumentation empfohlen, _fs.access_ zu verwenden, um Existenzprüfungen durchzuführen ( "Um zu überprüfen, ob eine Datei vorhanden ist, ohne sie zu manipulieren Danach wird fs.access() empfohlen. "). Beachten Sie jedoch, dass der nicht verfügbare Zugriff als Fehler betrachtet 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 fs.existsSync() verwenden:

_if (fs.existsSync(path)) {
    // Do something
}
_

Es wurde für mehrere Jahre veraltet, ist aber nicht mehr. Aus den Dokumenten:

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.)

2046
T.J. Crowder

Betrachtet man die Quelle, so gibt es eine synchrone Version von path.exists - path.existsSync. Sieht so aus, als wäre es in den Dokumenten verpasst worden.

Aktualisieren:

path.exists und path.existsSync sind jetzt veraltet Bitte benutzen Sie fs.exists und fs.existsSync.

Update 2016:

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

119
Jeff

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

var fs = require('fs');

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

Dies ist eine gute Antwort auf das von @broadband in den Kommentaren angesprochene EPERM-Problem. fileExists () ist wahrscheinlich in vielen Fällen keine gute Möglichkeit, darüber nachzudenken, da fileExists () keine wirklich boolesche Rückkehr versprechen kann. Möglicherweise können Sie definitiv feststellen, ob die Datei vorhanden ist oder nicht. Möglicherweise wird jedoch auch ein Berechtigungsfehler angezeigt. Der Berechtigungsfehler bedeutet nicht unbedingt, dass die Datei vorhanden ist, da möglicherweise keine Berechtigung für das Verzeichnis vorliegt, in dem sich die Datei befindet, auf die Sie prüfen. Und natürlich besteht die Möglichkeit, dass Sie bei der Prüfung auf das Vorhandensein von Dateien auf einen anderen Fehler stoßen.

Mein Code oben ist 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 beantwortet, wird dies häufig nicht das sein, was Sie wollen (Sie möchten nicht nur wissen, ob "etwas" an einem Pfad existiert, sondern sich wahrscheinlich darum kümmern, ob das "Ding" das existiert ist eine Datei oder ein Verzeichnis).

Die Quintessenz ist, dass Sie dies wahrscheinlich tun, wenn Sie überprüfen, ob eine Datei vorhanden ist, weil Sie beabsichtigen, basierend auf dem Ergebnis eine Aktion durchzuführen, und diese Logik (die Überprüfung und/oder die nachfolgende Aktion) sollte die Idee berücksichtigen Möglicherweise handelt es sich bei einem unter diesem Pfad gefundenen Element um eine Datei oder ein Verzeichnis, und bei der Überprüfung können EPERM- oder andere Fehler auftreten.

53
BobDickinson

Noch ein Update

Da ich selbst eine Antwort auf diese Frage benötige, habe ich die Knotendokumente nachgeschlagen. Anscheinend sollten Sie nicht fs.exists verwenden, sondern fs.open und outputted verwenden Fehler beim Erkennen, ob eine Datei nicht vorhanden ist:

aus den Dokumenten:

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

Insbesondere das Überprüfen, 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

20
Melbourne2991

Ich benutze die folgende Funktion, um zu testen, ob eine Datei existiert. Es fallen auch andere Ausnahmen auf. Falls es also Rechteprobleme gibt, z. Die Funktion chmod ugo-rwx filename oder in Windows Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list .. gibt die Ausnahmebedingung wie gewünscht zurück. Die Datei existiert, aber wir haben 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, Dokumentation zu NodeJS-Fehlern falls die Datei nicht existiert:

{
  [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 existieren:

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

fs.exists () ist veraltet und darf nicht verwendet werden https://nodejs.org/api/fs.html#fs_fs_exists_path_callback

Sie können den hier verwendeten 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 erhalten haben, können Sie es versuchen

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

Einige Antworten hier besagen, dass fs.exists und fs.existsSync beide veraltet sind. Nach den Unterlagen ist dies nicht mehr wahr. Nur fs.exists wird jetzt geändert:

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 fs.existsSync () verwenden, um synchron zu prüfen, ob eine Datei vorhanden ist.

4
jstice4all

Das path Modul bietet keine synchrone Version von path.exists, so dass Sie mit dem fs Modul herumspielen müssen.

Das schnellste, was ich mir vorstellen kann, ist die Verwendung von fs.realpathSync, das einen Fehler auslöst, den Sie abfangen müssen. Sie müssen also Ihre eigene Wrapper-Funktion mit try/catch erstellen.

2
Ivo Wetzel

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 einige Mühen und verwenden Sie eine Funktion, die in der 0.4.x-Verzweigung 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);
  });
});
0
user1248475

In den Dokumenten unter fs.stat() wird die Verwendung von fs.access() empfohlen, wenn Sie die Datei nicht manipulieren möchten. Es gab keine Begründung, könnte schneller oder weniger memeory Verwendung sein?

Ich benutze 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
Grallen