Operacje synchroniczne doskonale nadają się do wykonywania jednorazowych operacji na plikach / katalogach przed zwróceniem modułu. Na przykład ładowanie pliku konfiguracyjnego.
żartuje
1
@PaulDraper z ciepłą pamięcią podręczną nie jest prawdą we wszystkich przypadkach.
mikemaccana,
11
Niezależnie od wydajności, czasami chcesz po prostu uruchomić ją w sposób zsynchronizowany, aby uzyskać doświadczenie programisty. Na przykład, jeśli używasz Węzła do skryptu przetwarzania danych, który z założenia powinien blokować, w takim przypadku asynchronia existspo prostu dodaje niepotrzebne wywołania zwrotne.
Kunok,
2
Zdecydowanie +1 do oświadczenia Kunoka. W pozostałej części kodu komplikuję kod tylko wtedy, gdy jest to wąskie gardło, w którym szybkość ma znaczenie. Dlaczego nie miałbym zastosować tej zasady do odczytu plików? W wielu częściach wielu programów prostota / czytelność kodu może być ważniejsza niż szybkość wykonywania. Jeśli jest to wąskie gardło, użyję metod asynchronicznych, aby nie dopuścić do zatrzymania dalszego wykonywania kodu. W przeciwnym razie ... synchronizacja jest świetna. Nie ślepo nienawidzę synchronizacji.
BryanGrezeszak
3
Proszę ... nie „warte odnotowania”, ponieważ użytkownik wyraźnie pyta, jak to zrobić synchronicznie.
jClark,
Odpowiedzi:
2238
Odpowiedź na to pytanie zmieniała się na przestrzeni lat. prąd Odpowiedź jest tutaj na górze, a następnie przez różne odpowiedzi przez lata w porządku chronologicznym:
const fs = require("fs");// Or `import fs from "fs";` with ESMif(fs.existsSync(path)){// Do something}
Był przestarzały przez kilka lat, ale już nie jest. Z dokumentów:
Pamiętaj, że fs.exists()jest przestarzałe, ale fs.existsSync()nie jest. (Parametr wywołania zwrotnego fs.exists()akceptuje parametry niezgodne z innymi wywołaniami zwrotnymi Node.js. fs.existsSync()Nie używa wywołania zwrotnego.)
W szczególności poprosiłeś o sprawdzenie synchroniczne , ale jeśli zamiast tego możesz użyć sprawdzenia asynchronicznego (zwykle najlepiej z I / O), użyj, fs.promises.accessjeśli używasz asyncfunkcji lub fs.access(ponieważ existsjest przestarzałe ), jeśli nie:
W asyncfunkcji:
try{await fs.promises.access("somefile");// The check succeeded}catch(error){// The check failed}
Lub z oddzwanianiem:
fs.access("somefile", error =>{if(!error){// The check succeeded}else{// The check failed}});
Odpowiedzi historyczne
Oto odpowiedzi historyczne w kolejności chronologicznej:
Oryginalna odpowiedź z 2010 roku ( stat/ statSynclub lstat/ lstatSync)
Aktualizacja z września 2012 r. ( exists/ existsSync)
Aktualizacja z lutego 2015 r. (Zwracając uwagę na zbliżające się wycofanie exists/ existsSync, więc prawdopodobnie wróciliśmy do stat/ statSynclub lstat/ lstatSync)
Zaktualizuj grudzień 2015 r. (Jest też fs.access(path, fs.F_OK, function(){})/ fs.accessSync(path, fs.F_OK), ale zwróć uwagę, że jeśli plik / katalog nie istnieje, jest to błąd; fs.statzaleca się korzystanie z dokumentów, fs.accessjeśli chcesz sprawdzić istnienie bez otwierania)
Aktualizacja z grudnia 2016 r. fs.exists() Jest nadal przestarzała, ale fs.existsSync()nie jest już przestarzała. Możesz teraz bezpiecznie z niego korzystać.
Oryginalna odpowiedź z 2010 roku:
Możesz użyć statSynclub lstatSync( link do dokumentu ), który daje ci fs.Statsobiekt . Zasadniczo, jeśli dostępna jest synchroniczna wersja funkcji, będzie miała taką samą nazwę jak wersja asynchroniczna Syncna końcu. Podobnie statSyncjest z synchroniczną wersją stat; lstatSyncjest wersją synchroniczną lstatitp.
lstatSync mówi zarówno, czy coś istnieje, a jeśli tak, to czy jest to plik, czy katalog (lub w niektórych systemach plików, dowiązanie symboliczne, urządzenie blokowe, urządzenie znakowe itp.), np. czy musisz wiedzieć, czy istnieje i czy jest katalog:
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){// ...}
... i podobnie, jeśli jest to plik, istnieje isFile; jeśli jest to urządzenie blokowe, istnieje isBlockDeviceitp. itd. Uwaga try/catch; zgłasza błąd, jeśli pozycja w ogóle nie istnieje.
Jeśli nie obchodzi Cię, czym jest wpis i chcesz tylko wiedzieć, czy istnieje, możesz użyć path.existsSync(lub najnowszej wersji fs.existsSync), jak zauważył użytkownik 618408 :
var path = require('path');if(path.existsSync("/the/path")){// or fs.existsSync// ...}
Nie wymaga, try/catchale nie daje żadnych informacji o tym, co to jest, po prostu to, że tam jest. path.existsSynczostał wycofany dawno temu.
Uwaga dodatkowa: wyraźnie zapytałeś, jak sprawdzać synchronicznie , więc użyłem xyzSyncpowyższych wersji funkcji. Ale tam, gdzie to możliwe, we / wy naprawdę najlepiej unikać połączeń synchronicznych. Wywołania do podsystemu we / wy zajmują dużo czasu z punktu widzenia procesora. Zwróć uwagę, jak łatwo jest zadzwonić, lstata nie lstatSync:
// Is it a directory?
lstat('/the/path',function(err, stats){if(!err && stats.isDirectory()){// Yes it is}});
Ale jeśli potrzebujesz wersji synchronicznej, jest ona dostępna.
Aktualizacja z września 2012 r
Poniższa odpowiedź sprzed kilku lat jest teraz trochę nieaktualna. Obecny sposób polega na fs.existsSyncprzeprowadzeniu synchronicznego sprawdzania istnienia pliku / katalogu (lub oczywiście fs.existsna sprawdzeniu asynchronicznym) zamiast napath poniższych wersjach.
Przykład:
var fs = require('fs');if(fs.existsSync(path)){// Do something}// Or
fs.exists(path,function(exists){if(exists){// Do something}});
Aktualizacja z lutego 2015 r
I oto jesteśmy w 2015 roku, a dokumenty Node mówią teraz fs.existsSync(ifs.exists ) „będą przestarzałe”. (Ponieważ ludzie z Węzła uważają, że głupio jest sprawdzać, czy coś istnieje przed otwarciem, co to jest; ale to nie jedyny powód, aby sprawdzić, czy coś istnieje!)
Więc prawdopodobnie wróciliśmy do różnych statmetod ... Aż / chyba, że to się zmieni jeszcze raz, oczywiście.
Aktualizacja grudzień 2015 r
Nie wiem, jak długo tam był, ale jest też fs.access(path, fs.F_OK, ...)/fs.accessSync(path, fs.F_OK) . Przynajmniej w październiku 2016 r. fs.statDokumentacja zaleca używanie fs.accessdo sprawdzania istnienia ( zalecane jest „sprawdzenie, czy plik istnieje bez manipulowania nim później fs.access()” ). Pamiętaj jednak, że brak dostępu jest uważany za błąd , więc prawdopodobnie byłoby to najlepsze, jeśli spodziewasz się, że plik będzie dostępny:
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}});
Był przestarzały przez kilka lat, ale już nie jest. Z dokumentów:
Pamiętaj, że fs.exists()jest przestarzałe, ale fs.existsSync()nie jest. (Parametr wywołania zwrotnego fs.exists()akceptuje parametry niezgodne z innymi wywołaniami zwrotnymi Node.js. fs.existsSync()Nie używa wywołania zwrotnego.)
path.exists i path.existsSync zostały wycofane na korzyść fs.exists i fs.existsSync
Drew
15
„Ludzie węzłów uważają, że głupio jest sprawdzać, czy coś istnieje przed otwarciem, co to jest;” Dlaczego głupio jest sprawdzać, czy plik istnieje?
Petr Hurtak,
32
@PetrHurtak: Nie zawsze (ponieważ istnieje wiele powodów, aby sprawdzić istnienie), ale jeśli zamierzasz otworzyć plik, najlepiej po prostu openwywołać połączenie i obsłużyć wyjątek lub cokolwiek, jeśli plik nie był znaleziony. W końcu prawdziwy świat jest chaotyczny: jeśli najpierw sprawdzisz i już tam jest, to nie znaczy, że będzie tam nadal, gdy spróbujesz go otworzyć; jeśli najpierw sprawdzisz, a go nie ma, to nie znaczy, że nie będzie go ani chwili później. Takie rzeczy w taktach wydają się być przypadkami na krawędzi, ale pojawiają się cały czas . Więc jeśli zamierzasz otworzyć, nie ma sensu sprawdzać najpierw.
TJ Crowder,
13
I tutaj pomyślałem, że używanie anty-wzorca do sterowania przepływem jest anty-wzorzec: link
Napisałem małą bibliotekę, aby zastąpić starą existsfunkcję:is-there
Ionică Bizău,
6
currenct docs (wersja ~ 9) tylko oznaczone fs.existsjako przestarzałe, a fs.existsSyncnie jest!
Kunok,
57
Korzystając z obecnie zalecanych (od 2015 r.) Interfejsów API (według dokumentów węzła), robię to:
var fs = require('fs');function fileExists(filePath){try{return fs.statSync(filePath).isFile();}catch(err){returnfalse;}}
W odpowiedzi na kwestię EPERM podniesioną przez @broadband w komentarzach, porusza to dobry punkt. fileExists () prawdopodobnie nie jest dobrym sposobem na przemyślenie tego w wielu przypadkach, ponieważ fileExists () nie może tak naprawdę obiecać zwrotu logicznego. Możesz być w stanie definitywnie ustalić, że plik istnieje lub nie istnieje, ale możesz również otrzymać błąd uprawnień. Błąd uprawnień niekoniecznie oznacza, że plik istnieje, ponieważ może brakować uprawnień do katalogu zawierającego plik, który sprawdzasz. I oczywiście istnieje szansa, że napotkasz inny błąd w sprawdzaniu istnienia pliku.
Tak więc mój powyższy kod to tak naprawdę robiFileExistAndDoIHaveAccessToIt (), ale twoim pytaniem może być doesFileNotExistAndCouldICreateIt (), co byłoby zupełnie inną logiką (która musiałaby uwzględniać między innymi błąd EPERM).
Podczas gdy odpowiedź fs.existsSync odnosi się bezpośrednio do pytania zadanego tutaj, często nie jest to, czego chcesz (nie chcesz tylko wiedzieć, czy „coś” istnieje na ścieżce, prawdopodobnie zależy ci na tym, czy „rzecz” istnieje plik lub katalog).
Najważniejsze jest to, że jeśli sprawdzasz, czy plik istnieje, prawdopodobnie robisz to, ponieważ zamierzasz podjąć pewne działania w oparciu o wynik, a ta logika (sprawdzenie i / lub kolejne działanie) powinna uwzględniać pomysł że rzecz znaleziona w tej ścieżce może być plikiem lub katalogiem i że podczas sprawdzania możesz napotkać EPERM lub inne błędy.
Fajnie, dodałem || isDirectory (), aby uczynić z niego narzędzie do sprawdzania plików / folderów. var stats = fs.statSync (filePath); zwraca stats.isFile () || stats.isDirectory ();
Bob
4
Jeśli program nie ma praw dostępu do pliku, nadal zwraca wartość false, mimo że plik istnieje, tzn. Usuwa wszystkie platformy z pliku chmod ugo-rwx file.txt lub w systemie Windows Kliknij prawym przyciskiem myszy ... Komunikat o wyjątku: wyjątek fs.statSync (./ f.txt): Błąd: EPERM: operacja niedozwolona, stat „X: \ f.txt”. Więc ten przypadek nie jest objęty górnym kodem.
Internet szerokopasmowy
2
Wow, JS jest czasem opóźniony. Więc na pewno w 97% użyjesz tego pliku, ale nie masz prostego wykorzystania file.exists()dla 3% i zamiast tego zmuszasz nas do zawinięcia tego w try catch? Zyskaj prawdziwy ... Dziwka dnia.
wydalony
20
Kolejna aktualizacja
Konieczności odpowiedzi na to pytanie sobie, spojrzał w górę docs węzła zdaje należy nie używać fs.exists, zamiast używać fs.open i używać outputted błąd wykryć, jeśli plik nie istnieje:
z dokumentów:
fs.exists () jest anachronizmem i istnieje tylko z powodów historycznych. Prawie nigdy nie powinno być powodu, aby używać go we własnym kodzie.
W szczególności sprawdzenie, czy plik istnieje przed otwarciem, jest anty-wzorcem, który naraża cię na warunki wyścigu: inny proces może usunąć plik między wywołaniami fs.exists () i fs.open (). Wystarczy otworzyć plik i obsłużyć błąd, gdy go nie ma.
czy można to zrobić za pomocą openSync, a nie open
Greg Hornby
1
@GregHornby Wyobrażam sobie, że powinien działać tak samo z openSync
Melbourne2991
2
Dla tych, którzy wciąż potrzebują, exists a existsSyncja stworzyłem is-there.
Ionică Bizău
6
Ta deprecjacja mnie wkurza. Otwarcie pliku tylko w celu sprawdzenia, czy wystąpił błąd, wydaje się marnotrawstwem zasobów, gdy potrzebna jest tylko wiedza o istnieniu pliku.
Josh Hansen
11
Używam funkcji poniżej, aby sprawdzić, czy plik istnieje. Łapie także inne wyjątki. Więc w przypadku problemów z prawami np. chmod ugo-rwx filenameLub w Right Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..funkcji Windows
zwraca wyjątek tak jak powinien. Plik istnieje, ale nie mamy prawa dostępu do niego. Błędem byłoby ignorowanie tego rodzaju wyjątków.
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, ...}}
Niektóre odpowiedzi tutaj mówią to fs.existsi fs.existsSyncoba są przestarzałe. Według dokumentów nie jest to już prawdą. Tylko fs.existsjest teraz usunięty:
Zauważ, że fs.exists () jest przestarzała, ale fs.existsSync () nie jest. (Parametr wywołania zwrotnego do fs.exists () akceptuje parametry niespójne z innymi wywołaniami zwrotnymi Node.js. Fs.existsSync () nie używa wywołania zwrotnego).
Możesz więc bezpiecznie używać fs.existsSync () do synchronicznego sprawdzania, czy plik istnieje.
pathModuł nie zapewnia synchroniczną wersję path.existswięc trzeba oszukać wokół zfs modułu.
Najszybszą rzeczą, jaką mogę sobie wyobrazić, jest fs.realpathSyncrzucanie błędu, który musisz złapać, więc musisz stworzyć własną funkcję otoki za pomocą try / catch.
Testy fileSystem (fs) wyzwalają obiekty błędów, które następnie należy zawinąć w instrukcji try / catch. Zaoszczędź trochę wysiłku i skorzystaj z funkcji wprowadzonej w gałęzi 0.4.x.
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);});});
Path.exists jest teraz pod fs, więc jest fs.exists (ścieżka, wywołanie zwrotne)
Todd Moses
0
Dokumenty fs.stat()mówią, że należy użyć, fs.access()jeśli nie zamierzasz manipulować plikiem. Nie podało uzasadnienia, może być szybsze lub mniej użyteczne w pamięci?
Używam węzła do automatyzacji liniowej, więc pomyślałem, że dzielę funkcję, której używam do testowania istnienia pliku.
var fs = require("fs");function exists(path){//Remember file access time will slow your program.try{
fs.accessSync(path);}catch(err){returnfalse;}returntrue;}
Zwraca true, jeśli ścieżka istnieje, w przeciwnym razie false.
Rozwiązanie Async Promise
W kontekście asynchronicznym można po prostu napisać wersję asynchroniczną metodą synchronizacji za pomocą awaitsłowa kluczowego. Możesz po prostu zmienić metodę wywołania zwrotnego asynchronicznego w taką obietnicę:
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');}}
powinieneś zaktualizować swój kod dofunction 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
Możliwe, że jeśli chcesz wiedzieć, czy plik istnieje, planujesz go wymagać, jeśli tak jest.
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;}}
Stosowanie:
Działa zarówno dla katalogów, jak i plików
Jeśli element istnieje, zwraca ścieżkę do pliku lub katalogu
Jeśli element nie istnieje, zwraca wartość false
Przykład:
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);}
Upewnij się, że używasz operatora ===, aby sprawdzić, czy return jest równe false. Nie ma żadnego logicznego powodu, aby fs.realpathSync () zwrócił false w odpowiednich warunkach pracy, więc myślę, że powinno to działać w 100%.
Wolałbym zobaczyć rozwiązanie, które nie generuje błędu i wynikowego spadku wydajności. Z perspektywy API fs.exists () wydaje się być najbardziej eleganckim rozwiązaniem.
@Dan, dzięki. Usunąłem obcięty tekst. Nie pamiętam, co to była notatka. Jeśli mi przyjdzie, dodam notatki.
Timothy C. Quinn
1
Np. Usuwam mój komentarz.
Dan Dascalescu,
-2
Z odpowiedzi wynika, że nie ma w tym celu oficjalnego wsparcia API (jak w przypadku bezpośredniej i wyraźnej kontroli). Wiele odpowiedzi mówi, że używa statystyki, jednak nie są one ścisłe. Nie możemy na przykład założyć, że jakikolwiek błąd zgłoszony przez stat oznacza, że coś nie istnieje.
Powiedzmy, że próbujemy z czymś, co nie istnieje:
$ 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'}
Spróbujmy z czymś, co istnieje, ale nie mamy dostępu do:
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;};
Pytanie nie jest jasne, czy rzeczywiście chcesz, aby było synchroniczne, czy też chcesz, aby było napisane tak, jakby było synchroniczne. W tym przykładzie użyto funkcji Oczekiwanie / Async, dzięki czemu jest zapisywane tylko synchronicznie, ale działa asynchronicznie.
Oznacza to, że musisz tak to nazwać na najwyższym poziomie:
Alternatywą jest użycie .then i .catch na obietnicy zwróconej z wywołania asynchronicznego, jeśli jest ona potrzebna dalej.
Jeśli chcesz sprawdzić, czy coś istnieje, dobrą praktyką jest również upewnienie się, że jest to właściwy typ rzeczy, np. Katalog lub plik. Jest to uwzględnione w przykładzie. Jeśli nie jest to dowiązanie symboliczne, musisz użyć lstat zamiast stat, ponieważ stat automatycznie przejdzie przez linki.
Możesz zastąpić cały asynchroniczny kod, aby zsynchronizować kod tutaj i zamiast tego użyć statSync. Spodziewaj się jednak, że gdy asynchronizacja i oczekiwanie staną się uniwersalne, połączenia synchronizacji staną się w końcu zbędne, aby zostać zdeprecjonowane (w przeciwnym razie będziesz musiał zdefiniować je wszędzie i wyżej, tak jak w przypadku asynchronizacji, co czyni je naprawdę bezcelowymi).
Pierwotne pytanie tego nie precyzuje. Pokazuję też, jak robić rzeczy jednoznacznie. Wiele odpowiedzi może powodować błędy z powodu niejasności. Ludzie często chcą programować rzeczy tak, aby wyglądały synchronicznie, ale niekoniecznie chcą synchronicznego wykonywania. statSync to nie to samo co kod, który pokazałem. Oba opisy tego, co jest rzeczywiście pożądane, są niejednoznaczne, więc narzucasz tylko swoje osobiste interpretacje. Jeśli znajdziesz odpowiedź, której nie rozumiesz, lepiej po prostu zapytać w komentarzach lub PM, aby dowiedzieć się, jakie zmiany są potrzebne.
jgmjgm
1
Jeśli chcesz, możesz również ukraść mój przykładowy kod, nazwij go odpowiednio, umieść na github, dodaj go do npm, a wtedy odpowiedź będzie tylko jedna linia / link: D.
jgmjgm
Kod jest krótki dla przykładu, ale możesz przesłać sugestię edycji, aby dołączyć &&! IsFile lub sprawdzić linki symboliczne itp. (Ponownie, chociaż pytanie nigdy nie mówi wprost, że tego właśnie chcą). Jak już wskazałem, moja odpowiedź spełnia jedną interpretację pytania i nie robi tego samego, co propozycja jednoliniowa.
exists
po prostu dodaje niepotrzebne wywołania zwrotne.Odpowiedzi:
Odpowiedź na to pytanie zmieniała się na przestrzeni lat. prąd Odpowiedź jest tutaj na górze, a następnie przez różne odpowiedzi przez lata w porządku chronologicznym:
Aktualna odpowiedź
Możesz użyć
fs.existsSync()
:Był przestarzały przez kilka lat, ale już nie jest. Z dokumentów:
W szczególności poprosiłeś o sprawdzenie synchroniczne , ale jeśli zamiast tego możesz użyć sprawdzenia asynchronicznego (zwykle najlepiej z I / O), użyj,
fs.promises.access
jeśli używaszasync
funkcji lubfs.access
(ponieważexists
jest przestarzałe ), jeśli nie:W
async
funkcji:Lub z oddzwanianiem:
Odpowiedzi historyczne
Oto odpowiedzi historyczne w kolejności chronologicznej:
(
stat
/statSync
lublstat
/lstatSync
)(
exists
/existsSync
)(Zwracając uwagę na zbliżające się wycofanie
exists
/existsSync
, więc prawdopodobnie wróciliśmy dostat
/statSync
lublstat
/lstatSync
)(Jest też
fs.access(path, fs.F_OK, function(){})
/fs.accessSync(path, fs.F_OK)
, ale zwróć uwagę, że jeśli plik / katalog nie istnieje, jest to błąd;fs.stat
zaleca się korzystanie z dokumentów,fs.access
jeśli chcesz sprawdzić istnienie bez otwierania)fs.exists()
Jest nadal przestarzała, alefs.existsSync()
nie jest już przestarzała. Możesz teraz bezpiecznie z niego korzystać.Oryginalna odpowiedź z 2010 roku:
Możesz użyć
statSync
lublstatSync
( link do dokumentu ), który daje cifs.Stats
obiekt . Zasadniczo, jeśli dostępna jest synchroniczna wersja funkcji, będzie miała taką samą nazwę jak wersja asynchronicznaSync
na końcu. PodobniestatSync
jest z synchroniczną wersjąstat
;lstatSync
jest wersją synchronicznąlstat
itp.lstatSync
mówi zarówno, czy coś istnieje, a jeśli tak, to czy jest to plik, czy katalog (lub w niektórych systemach plików, dowiązanie symboliczne, urządzenie blokowe, urządzenie znakowe itp.), np. czy musisz wiedzieć, czy istnieje i czy jest katalog:... i podobnie, jeśli jest to plik, istnieje
isFile
; jeśli jest to urządzenie blokowe, istniejeisBlockDevice
itp. itd. Uwagatry/catch
; zgłasza błąd, jeśli pozycja w ogóle nie istnieje.Jeśli nie obchodzi Cię, czym jest wpis i chcesz tylko wiedzieć, czy istnieje, możesz użyćpath.existsSync
(lub najnowszej wersjifs.existsSync
), jak zauważył użytkownik 618408 :Nie wymaga,try/catch
ale nie daje żadnych informacji o tym, co to jest, po prostu to, że tam jest.path.existsSync
został wycofany dawno temu.Uwaga dodatkowa: wyraźnie zapytałeś, jak sprawdzać synchronicznie , więc użyłem
xyzSync
powyższych wersji funkcji. Ale tam, gdzie to możliwe, we / wy naprawdę najlepiej unikać połączeń synchronicznych. Wywołania do podsystemu we / wy zajmują dużo czasu z punktu widzenia procesora. Zwróć uwagę, jak łatwo jest zadzwonić,lstat
a nielstatSync
:Ale jeśli potrzebujesz wersji synchronicznej, jest ona dostępna.
Aktualizacja z września 2012 r
Poniższa odpowiedź sprzed kilku lat jest teraz trochę nieaktualna. Obecny sposób polega na
fs.existsSync
przeprowadzeniu synchronicznego sprawdzania istnienia pliku / katalogu (lub oczywiściefs.exists
na sprawdzeniu asynchronicznym) zamiast napath
poniższych wersjach.Przykład:
Aktualizacja z lutego 2015 r
I oto jesteśmy w 2015 roku, a dokumenty Node mówią teraz
fs.existsSync
(ifs.exists
) „będą przestarzałe”. (Ponieważ ludzie z Węzła uważają, że głupio jest sprawdzać, czy coś istnieje przed otwarciem, co to jest; ale to nie jedyny powód, aby sprawdzić, czy coś istnieje!)Więc prawdopodobnie wróciliśmy do różnych
stat
metod ... Aż / chyba, że to się zmieni jeszcze raz, oczywiście.Aktualizacja grudzień 2015 r
Nie wiem, jak długo tam był, ale jest też
fs.access(path, fs.F_OK, ...)
/fs.accessSync(path, fs.F_OK)
. Przynajmniej w październiku 2016 r.fs.stat
Dokumentacja zaleca używaniefs.access
do sprawdzania istnienia ( zalecane jest „sprawdzenie, czy plik istnieje bez manipulowania nim późniejfs.access()
” ). Pamiętaj jednak, że brak dostępu jest uważany za błąd , więc prawdopodobnie byłoby to najlepsze, jeśli spodziewasz się, że plik będzie dostępny:Aktualizacja z grudnia 2016 r
Możesz użyć
fs.existsSync()
:Był przestarzały przez kilka lat, ale już nie jest. Z dokumentów:
źródło
open
wywołać połączenie i obsłużyć wyjątek lub cokolwiek, jeśli plik nie był znaleziony. W końcu prawdziwy świat jest chaotyczny: jeśli najpierw sprawdzisz i już tam jest, to nie znaczy, że będzie tam nadal, gdy spróbujesz go otworzyć; jeśli najpierw sprawdzisz, a go nie ma, to nie znaczy, że nie będzie go ani chwili później. Takie rzeczy w taktach wydają się być przypadkami na krawędzi, ale pojawiają się cały czas . Więc jeśli zamierzasz otworzyć, nie ma sensu sprawdzać najpierw.Patrząc na źródło, istnieje synchroniczna wersja
path.exists
-path.existsSync
. Wygląda na to, że zgubił się w dokumentacji.Aktualizacja:
path.exists
ipath.existsSync
są teraz przestarzałe .Proszę użyć.fs.exists
ifs.existsSync
Aktualizacja 2016:
fs.exists
izostały wycofane . Zamiast tego użyj fs.stat () lub fs.access () .fs.existsSync
równieżAktualizacja 2019:
użyć
fs.existsSync
. To nie jest przestarzałe. https://nodejs.org/api/fs.html#fs_fs_existssync_pathźródło
fs.existsSync
.exists
funkcję:is-there
fs.exists
jako przestarzałe, afs.existsSync
nie jest!Korzystając z obecnie zalecanych (od 2015 r.) Interfejsów API (według dokumentów węzła), robię to:
W odpowiedzi na kwestię EPERM podniesioną przez @broadband w komentarzach, porusza to dobry punkt. fileExists () prawdopodobnie nie jest dobrym sposobem na przemyślenie tego w wielu przypadkach, ponieważ fileExists () nie może tak naprawdę obiecać zwrotu logicznego. Możesz być w stanie definitywnie ustalić, że plik istnieje lub nie istnieje, ale możesz również otrzymać błąd uprawnień. Błąd uprawnień niekoniecznie oznacza, że plik istnieje, ponieważ może brakować uprawnień do katalogu zawierającego plik, który sprawdzasz. I oczywiście istnieje szansa, że napotkasz inny błąd w sprawdzaniu istnienia pliku.
Tak więc mój powyższy kod to tak naprawdę robiFileExistAndDoIHaveAccessToIt (), ale twoim pytaniem może być doesFileNotExistAndCouldICreateIt (), co byłoby zupełnie inną logiką (która musiałaby uwzględniać między innymi błąd EPERM).
Podczas gdy odpowiedź fs.existsSync odnosi się bezpośrednio do pytania zadanego tutaj, często nie jest to, czego chcesz (nie chcesz tylko wiedzieć, czy „coś” istnieje na ścieżce, prawdopodobnie zależy ci na tym, czy „rzecz” istnieje plik lub katalog).
Najważniejsze jest to, że jeśli sprawdzasz, czy plik istnieje, prawdopodobnie robisz to, ponieważ zamierzasz podjąć pewne działania w oparciu o wynik, a ta logika (sprawdzenie i / lub kolejne działanie) powinna uwzględniać pomysł że rzecz znaleziona w tej ścieżce może być plikiem lub katalogiem i że podczas sprawdzania możesz napotkać EPERM lub inne błędy.
źródło
file.exists()
dla 3% i zamiast tego zmuszasz nas do zawinięcia tego w try catch? Zyskaj prawdziwy ... Dziwka dnia.Kolejna aktualizacja
Konieczności odpowiedzi na to pytanie sobie, spojrzał w górę docs węzła zdaje należy nie używać fs.exists, zamiast używać fs.open i używać outputted błąd wykryć, jeśli plik nie istnieje:
z dokumentów:
http://nodejs.org/api/fs.html#fs_fs_exists_path_callback
źródło
exists
aexistsSync
ja stworzyłemis-there
.Używam funkcji poniżej, aby sprawdzić, czy plik istnieje. Łapie także inne wyjątki. Więc w przypadku problemów z prawami np.
chmod ugo-rwx filename
Lub wRight Click -> Properties -> Security -> Advanced -> Permission entries: empty list ..
funkcji Windows zwraca wyjątek tak jak powinien. Plik istnieje, ale nie mamy prawa dostępu do niego. Błędem byłoby ignorowanie tego rodzaju wyjątków.Wyjście wyjątku, dokumentacja błędów nodejs w przypadku, gdy plik nie istnieje:
Wyjątek w przypadku, gdy nie mamy uprawnień do pliku, ale istnieje:
źródło
fs.exists () jest przestarzałe, nie używaj go https://nodejs.org/api/fs.html#fs_fs_exists_path_callback
Możesz zaimplementować podstawową metodę nodejs zastosowaną w tym miejscu: https://github.com/nodejs/node-v0.x-archive/blob/master/lib/module.js#L86
to zwróci obiekt statystyki, a kiedy już dostaniesz obiekt statystyki, możesz spróbować
źródło
Niektóre odpowiedzi tutaj mówią to
fs.exists
ifs.existsSync
oba są przestarzałe. Według dokumentów nie jest to już prawdą. Tylkofs.exists
jest teraz usunięty:Możesz więc bezpiecznie używać fs.existsSync () do synchronicznego sprawdzania, czy plik istnieje.
źródło
path
Moduł nie zapewnia synchroniczną wersjępath.exists
więc trzeba oszukać wokół zfs
modułu.Najszybszą rzeczą, jaką mogę sobie wyobrazić, jest
fs.realpathSync
rzucanie błędu, który musisz złapać, więc musisz stworzyć własną funkcję otoki za pomocą try / catch.źródło
Testy fileSystem (fs) wyzwalają obiekty błędów, które następnie należy zawinąć w instrukcji try / catch. Zaoszczędź trochę wysiłku i skorzystaj z funkcji wprowadzonej w gałęzi 0.4.x.
źródło
Dokumenty
fs.stat()
mówią, że należy użyć,fs.access()
jeśli nie zamierzasz manipulować plikiem. Nie podało uzasadnienia, może być szybsze lub mniej użyteczne w pamięci?Używam węzła do automatyzacji liniowej, więc pomyślałem, że dzielę funkcję, której używam do testowania istnienia pliku.
źródło
zaktualizowany asnwer dla tych osób „poprawnie”, wskazując, że nie odpowiada bezpośrednio na pytanie, więcej oferuje alternatywną opcję.
Rozwiązanie synchronizacji:
fs.existsSync('filePath')
zobacz także dokumenty tutaj .Rozwiązanie Async Promise
W kontekście asynchronicznym można po prostu napisać wersję asynchroniczną metodą synchronizacji za pomocą
await
słowa kluczowego. Możesz po prostu zmienić metodę wywołania zwrotnego asynchronicznego w taką obietnicę:dokumenty dotyczące dostępu ().
źródło
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); }, ); }); }
Możliwe, że jeśli chcesz wiedzieć, czy plik istnieje, planujesz go wymagać, jeśli tak jest.
źródło
Oto proste rozwiązanie tego opakowania:
Stosowanie:
Przykład:
Upewnij się, że używasz operatora ===, aby sprawdzić, czy return jest równe false. Nie ma żadnego logicznego powodu, aby fs.realpathSync () zwrócił false w odpowiednich warunkach pracy, więc myślę, że powinno to działać w 100%.
Wolałbym zobaczyć rozwiązanie, które nie generuje błędu i wynikowego spadku wydajności. Z perspektywy API fs.exists () wydaje się być najbardziej eleganckim rozwiązaniem.
źródło
Z odpowiedzi wynika, że nie ma w tym celu oficjalnego wsparcia API (jak w przypadku bezpośredniej i wyraźnej kontroli). Wiele odpowiedzi mówi, że używa statystyki, jednak nie są one ścisłe. Nie możemy na przykład założyć, że jakikolwiek błąd zgłoszony przez stat oznacza, że coś nie istnieje.
Powiedzmy, że próbujemy z czymś, co nie istnieje:
Spróbujmy z czymś, co istnieje, ale nie mamy dostępu do:
Przynajmniej będziesz chciał:
Pytanie nie jest jasne, czy rzeczywiście chcesz, aby było synchroniczne, czy też chcesz, aby było napisane tak, jakby było synchroniczne. W tym przykładzie użyto funkcji Oczekiwanie / Async, dzięki czemu jest zapisywane tylko synchronicznie, ale działa asynchronicznie.
Oznacza to, że musisz tak to nazwać na najwyższym poziomie:
Alternatywą jest użycie .then i .catch na obietnicy zwróconej z wywołania asynchronicznego, jeśli jest ona potrzebna dalej.
Jeśli chcesz sprawdzić, czy coś istnieje, dobrą praktyką jest również upewnienie się, że jest to właściwy typ rzeczy, np. Katalog lub plik. Jest to uwzględnione w przykładzie. Jeśli nie jest to dowiązanie symboliczne, musisz użyć lstat zamiast stat, ponieważ stat automatycznie przejdzie przez linki.
Możesz zastąpić cały asynchroniczny kod, aby zsynchronizować kod tutaj i zamiast tego użyć statSync. Spodziewaj się jednak, że gdy asynchronizacja i oczekiwanie staną się uniwersalne, połączenia synchronizacji staną się w końcu zbędne, aby zostać zdeprecjonowane (w przeciwnym razie będziesz musiał zdefiniować je wszędzie i wyżej, tak jak w przypadku asynchronizacji, co czyni je naprawdę bezcelowymi).
źródło