2015-08-04 10 views
10

Zgodnie z documentation plik node.js fs.exists() zostanie uznany za przestarzały. Ich argumentacja:node.js fs.exists() będzie przestarzałe, co należy zamiast tego użyć?

fs.exists() jest anachronizmem i istnieje tylko z przyczyn historycznych. Nie powinno prawie nigdy istnieć powód, aby używać go we własnym kodzie.

W szczególności sprawdzenie, czy plik istnieje przed otwarciem, jest wzorcem zapobiegającym narażeniu na warunki wyścigu: inny proces może usunąć plik między wywołaniami fs.exists() i fs.open(). Po prostu otwórz plik i obsłuż błąd, gdy go nie ma.

fs.exists() zostanie uznany za przestarzały.

Obecnie używam go przed przenoszeniem plików, ponieważ fs.rename() wydaje się po cichu nadpisywać pliki o tej samej nazwie w folderze docelowym.

Moje pytanie brzmi; co powinienem zamiast tego użyć, aby zapobiec nadpisywaniu pliku fs.rename() w folderze docelowym? Zakładam, że istnieje sposób, o którym nie wiem. W przeciwnym razie nie widzę powodu, dla którego fs.exists() ma być przestarzałe.

Używanie fs.open() jako sugerowanej wydaje się przesadą, ponieważ nie chcę otwierać pliku.


Edit, jak na życzenie użytkownika @ jfriend00 uzyskać więcej informacji o tym, co robię.

Robię aplikację Electron, w której użytkownik może sortować pliki do różnych katalogów. Nie jest to oprogramowanie serwerowe, przeznaczone jest do codziennego korzystania z komputerów, obsługi ich dokumentów. Jest to kod do tej pory do przenoszenia pliku:

function moveFile(destIndex){ 
    var from = queue[currentQueueIndex].path; 
    var to = destinations[destIndex].path + path.sep + path.basename(from); 
    console.log("[i] Move file (from/to): "); 
    console.log(from); 
    console.log(to); 

    //Check if file exists, if yes: give them the choice to cancel. 
    fs.stat(to, function (err, stats) { 
     if (err){ 
      move(from, to); 
     } else { 
      var confirmed = confirm("File already exists, will overwrite."); 
      if (confirmed) { 
       move(from, to); 
      } 
     } 
    }); 
    next(); //Show the next file to the user 
} 

function move(from, to){ 
    fs.rename(from, to, function (err) { 
     if (err) throw err; 
     console.log('[i] Move successful'); 
     queue[currentQueueIndex].path = to; 
     queue[currentQueueIndex].moved = true; 
    }); 
} 

Po pierwszym komentarzu, część zaczynając fs.stat, sprawdzić, czy plik mam zamiar stworzyć z fs.rename już istnieje. Sądzę, że jest to zależne od warunków wyścigowych, ale nie mogę stwierdzić, że fs.rename w jakikolwiek sposób obsługuje duplikaty.
Ponieważ ta aplikacja jest przeznaczona do "komputerów domowych", nie sądzę, aby miał miejsce scenariusz, w którym plik znika między sprawdzaniem statystyk a zmianą nazwy. Ale nadal, im więcej potencjalnych problemów mogę uniknąć, tym lepiej.

+1

Co dokładnie próbujesz użyć 'fs .exists() 'for? Potrzebujemy jeszcze kilku szczegółów na temat sekwencji kodu, zanim będziemy mogli zasugerować coś, co nie jest podatne na warunki wyścigu? Chodzi o to, że każdy substytut, który tylko sprawdza istnienie, a następnie przeprowadza akcję opartą na tej wiedzy, podlega warunkom wyścigu i istnieje prawdopodobnie lepszy sposób na jego kodowanie. – jfriend00

+0

@ jfriend00 - Dodałem, co robię do głównego pytania, a także kod do niego. – Blargmode

+0

W przypadku monitu użytkownika końcowego na komputerze o niewielkiej liczbie użytkowników, wynikowy wyścig prawdopodobnie nie dotyczy. Prawdziwą odpowiedzią byłaby wersja 'fs.rename()', która nie nadpisałaby celu, więc możesz go nazwać w ten sposób i tylko wtedy, gdy nie uda się przepisać, ponieważ cel istnieje, wtedy pytasz i zmieniasz argument do 'fs.rename()', aby umożliwić nadpisanie. To nigdy nie zostanie nadpisane bez pierwszego pytania. Ale zgodziłbym się - prawdopodobnie nie jest potrzebny w tego typu przypadku użycia. – jfriend00

Odpowiedz

5

The io.js docs wymienia użycie fs.stat() lub fs.access() zamiast fs.exists().

+0

fs.stat() wygląda obiecująco, ale kiedy próbuję go użyć 'var stat = fs.statSync (plik);' otrzymuję błąd ENOENT na plikach, które nie istnieją. Jak sobie z tym poradzić? – Blargmode

+0

Mam to działa. Wstawiłem funkcję zmiany nazwy w funkcji statystycznej, odwrotnej do [czwartego przykładu tutaj] (https://iojs.org/api/fs.html#fs_file_system), co pozwoliło mi używać statystyk, a nie statSync. Chociaż 'if (error) doSomething();' wydaje się nieco dziwne. – Blargmode

+0

@Blargmode - Wygląda na to, że to, co robisz, nadal podlega warunkom wyścigu. – jfriend00

0

Oto przykład za pomocą fs.stat: -

fs.stat('mycustomfile.csv', function (err, stats) { 
    console.log(stats);//here we got all information of file in stats variable 
    if (err) { 
     return console.error(err); 
    } 
    fs.unlink('mycustomfile.csv',function(err){ 
     if(err) return console.log(err); 
     console.log('file deleted successfully'); 
    }); 
}); 
2

Zastosowanie fs.existsSync().

fs.existsSync() nie jest przestarzałe.

https://nodejs.org/api/fs.html#fs_fs_existssync_path

fs.existsSync (ścieżka)

Dodane w: v0.1.21 ścieżka | Synchroniczna wersja fs.exists(). Zwraca true, jeśli plik istnieje, w przeciwnym razie false.

Uwaga: fs.exists() jest przestarzałe, ale fs.existsSync() nie jest. (Parametr callback> do fs.exists() akceptuje parametry niezgodne z innymi wywoływaniami> Node.js.fs.existsSync() nie używa wywołania zwrotnego.)

+0

Zdaje się, że funkcja ta jest przestarzała, a nie tylko zmiana interfejsu funkcji, aby była spójna z innymi wywołaniami Node.js. – Marvin

Powiązane problemy