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:
const fs = require("fs");// Or `import fs from "fs";` with ESMif(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.
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}});
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.)
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
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.existsund fs.existsSyncwurden ebenfalls veraltet . Verwenden Sie stattdessen fs.stat () oder fs.access () .
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){returnfalse;}}
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.
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.
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.");returnfalse;}
console.log("Exception fs.statSync ("+ path +"): "+ e);throw e;// something else went wrong, we don't have rights, ...}}
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.
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.
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);});});
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){returnfalse;}returntrue;}
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){returnnewPromise((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.}asyncfunction doSomething(){var exists =await fileExists('filePath');if(exists){
console.log('file exists');}}
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){returnfalse;}}
var fs = require('fs')function getFileRealPath(s){try{return fs.realpathSync(s);}catch(e){returnfalse;}}
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.
@ 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:
let dir_exists =async path =>{let stat;try{
stat =await(newPromise((resolve, reject)=> require('fs').stat(path,(err, result)=> err ? reject(err): resolve(result))));}catch(e){if(e.code ==='ENOENT')returnfalse;throw e;}if(!stat.isDirectory())thrownewError('Not a directory.');returntrue;};
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:
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).
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.
exists
fügt async in diesem Fall nur unnötige Rückrufe hinzu.Antworten:
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()
:Es war mehrere Jahre veraltet, ist es aber nicht mehr. Aus den Dokumenten:
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.access
Sie diese , wenn Sieasync
Funktionen verwenden, oderfs.access
(da sieexists
veraltet ist ), wenn nicht:In einer
async
Funktion:Oder mit einem Rückruf:
Historische Antworten
Hier sind die historischen Antworten in chronologischer Reihenfolge:
(
stat
/statSync
oderlstat
/lstatSync
)(
exists
/existsSync
)(Angesichts der bevorstehenden Abwertung von
exists
/existsSync
sind wir wahrscheinlich wieder beistat
/statSync
oderlstat
/lstatSync
)(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ürfs.stat
empfehlen die Verwendung ,fs.access
wenn Sie benötigen die Existenz ohne Öffnung zu überprüfen)fs.exists()
ist immer noch veraltet, aberfs.existsSync()
nicht mehr veraltet. So können Sie es jetzt sicher verwenden.Ursprüngliche Antwort von 2010:
Sie können
statSync
oderlstatSync
( docs link ) verwenden, um einfs.Stats
Objekt zu erhalten . Wenn eine synchrone Version einer Funktion verfügbar ist, hat sie im Allgemeinen denselben Namen wie die asynchrone VersionSync
am Ende. SostatSync
ist die synchrone Version vonstat
;lstatSync
ist die synchrone Version vonlstat
usw.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:... und ähnlich, wenn es eine Datei ist, gibt es
isFile
; Wenn es sich um ein Blockgerät handelt, gibt esisBlockDevice
usw. usw. Beachten Sie dietry/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 Siepath.existsSync
(oder mit der neuesten Versionfs.existsSync
) Folgendes verwenden , wie von user618408 angegeben :Es erfordert keintry/catch
, gibt Ihnen aber keine Informationen darüber, was das Ding ist, nur dass es da ist.path.existsSync
wurde vor langer Zeit veraltet.Randnotiz: Sie haben ausdrücklich gefragt, wie Sie synchron prüfen sollen , daher habe ich die
xyzSync
Versionen 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,lstat
anstattlstatSync
: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ürlichfs.exists
eine asynchrone Prüfung) anstelle der folgendenpath
Versionen durchzuführen.Beispiel:
Update Februar 2015
Und hier sind wir im Jahr 2015 und die Node-Dokumente sagen jetzt, dass
fs.existsSync
(undfs.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
stat
Methoden ... 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 derfs.stat
Dokumentation empfohlenfs.access
, Existenzprüfungen durchzuführen ( "Esfs.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:Update Dezember 2016
Sie können verwenden
fs.existsSync()
:Es war mehrere Jahre veraltet, ist es aber nicht mehr. Aus den Dokumenten:
quelle
open
Aufruf 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.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.exists
undpath.existsSync
sind jetzt veraltet .Bitte benutzen Sie.fs.exists
undfs.existsSync
Update 2016:
fs.exists
undveraltet . Verwenden Sie stattdessen fs.stat () oder fs.access () .fs.existsSync
wurden ebenfallsUpdate 2019:
verwenden
fs.existsSync
. Es ist nicht veraltet. https://nodejs.org/api/fs.html#fs_fs_existssync_pathquelle
fs.existsSync
.exists
Funktion zu ersetzen :is-there
fs.exists
als veraltet gekennzeichnet, solange diesfs.existsSync
nicht der Fall ist!Mit den derzeit empfohlenen (ab 2015) APIs (gemäß den Knotendokumenten) mache ich Folgendes:
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.
quelle
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.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:
http://nodejs.org/api/fs.html#fs_fs_exists_path_callback
quelle
exists
undexistsSync
ich geschaffen habeis-there
.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 filename
oder 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.Ausnahmeausgabe, NodeJS-Fehlerdokumentation für den Fall, dass keine Datei vorhanden ist:
Ausnahme für den Fall, dass wir keine Rechte an der Datei haben, aber vorhanden sind:
quelle
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
Dadurch wird das Statistikobjekt zurückgegeben. Sobald Sie das Statistikobjekt haben, können Sie es versuchen
quelle
Einige Antworten hier sagen das
fs.exists
undfs.existsSync
sind beide veraltet. Laut den Dokumenten ist dies nicht mehr wahr. Nurfs.exists
ist jetzt veraltet:Sie können also sicher mit fs.existsSync () synchron prüfen, ob eine Datei vorhanden ist.
quelle
Das
path
Modul bietet keine synchrone Version von,path.exists
sodass Sie mit demfs
Modul herumspielen müssen.Das Schnellste, was ich mir vorstellen kann, ist die Verwendung
fs.realpathSync
eines Fehlers, den Sie abfangen müssen. Sie müssen also Ihre eigene Wrapper-Funktion mit einem Versuch / Fang erstellen.quelle
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.
quelle
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.
quelle
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 .Async Promise-Lösung
In einem asynchronen Kontext können Sie die asynchrone Version einfach synchron mit dem
await
Schlüsselwort schreiben . Sie können die asynchrone Rückrufmethode einfach in ein Versprechen wie das folgende umwandeln:die Dokumente bei access ().
quelle
function 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); }, ); }); }
Wenn Sie wissen möchten, ob eine Datei vorhanden ist, möchten Sie diese möglicherweise anfordern, wenn dies der Fall ist.
quelle
Hier ist eine einfache Wrapper-Lösung dafür:
Verwendungszweck:
Beispiel:
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.
quelle
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:
Versuchen wir es mit etwas, das existiert, auf das wir aber keinen Zugriff haben:
Zumindest wollen Sie:
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:
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).
quelle