W mojej aplikacji Node muszę usunąć katalog, który zawiera niektóre pliki, ale fs.rmdir
działa tylko w pustych katalogach. W jaki sposób mogę to zrobić?
node.js
filesystems
sachin
źródło
źródło
fs.readdir(dirPath)
dla tablicy ścieżek w folderze, iteruj,fs.unlink(filename)
aby usunąć każdy plik, a następnie w końcu,fs.rmdir(dirPath)
aby usunąć teraz pusty folder. Jeśli musisz się powtórzyć, sprawdźfs.lstat(filename).isDirectory()
.Odpowiedzi:
Jest do tego moduł o nazwie
rimraf
( https://npmjs.org/package/rimraf ). Zapewnia taką samą funkcjonalność jakrm -Rf
Wykorzystanie asynchroniczne :
Wykorzystanie synchronizacji :
źródło
deleteFolderRecursive
w poniższej odpowiedzi?recursive
opcji: stackoverflow.com/a/57866165/6269864Aby usunąć folder synchronicznie
źródło
var curPath = path + "/" + file;
zvar curPath = p.join(path, file);
warunkiem, że zawiera moduł ścieżki:var p = require("path")
path.join(dirpath, file)
powinno być lepiej niżpath + "/" + file
Większość osób korzystających
fs
z Node.js chciałoby funkcji zbliżonych do „uniksowego sposobu” radzenia sobie z plikami. Korzystam z fs-extra, aby przynieść wszystkie fajne rzeczy:Jeszcze lepiej, fs-extra jest spadkiem w zastępstwie natywnego fs. Wszystkie metody w fs są niezmodyfikowane i dołączone do niego. Oznacza to, że możesz zastąpić fs przez fs-extra :
Następnie możesz usunąć folder w ten sposób:
źródło
removeSync('/tmp/myFolder')
Od 2019 roku ...
Począwszy od Node.js 12.10.0 ,
fs.rmdirSync
obsługujerecursive
opcje, dzięki czemu możesz w końcu wykonać:Gdzie
recursive
opcja rekurencyjnie usuwa cały katalog.źródło
recursive: true
i usuwa niepuste foldery bez reklamacji.fs.rmdir(path[, options], callback)
lubfs.rmdirSync(path[, options])
fs.rmdir
jest eksperymentalna ze stabilnością 1. „Stabilność: 1 - eksperymentalna. Funkcja nie podlega regułom wersjonowania semantycznego. W dowolnym przyszłe wydanie. Korzystanie z tej funkcji nie jest zalecane w środowiskach produkcyjnych ”.Moja zmodyfikowana odpowiedź od @oconnecp ( https://stackoverflow.com/a/25069828/3027390 )
Używa path.join dla lepszego doświadczenia na różnych platformach. Więc nie zapomnij tego wymagać.
Również przemianowano funkcję na
rimraf
;)źródło
Zwykle nie wskrzeszam starych wątków, ale tutaj jest dużo churn i bez odpowiedzi rimrafa wszystkie te wydają mi się zbyt skomplikowane.
Po pierwsze we współczesnym węźle (> = v8.0.0) możesz uprościć ten proces, używając tylko modułów rdzenia węzła, w pełni asynchronicznych, i równolegle rozłączać pliki jednocześnie w funkcji pięciu linii i nadal zachować czytelność:
Z drugiej strony strażnik przed atakami z przejścia ścieżki jest nieodpowiedni dla tej funkcji, ponieważ
rm -rf
, ponieważ wymaga argumentu i pozwala użytkownikowi na to,rm -rf /
jeśli zostanie o to poproszony. Skrypt byłby odpowiedzialny za ochronęrm
samego programu..isDirectory()
tofalse
na sym-linków i nie są odłączone recursed się.Wreszcie, istnieje rzadki warunek wyścigu, w którym rekursja może popełnić błąd, jeśli jeden z wpisów został rozłączony lub usunięty poza tym skryptem we właściwym czasie, gdy ta rekurencja jest uruchomiona. Ponieważ ten scenariusz nie jest typowy w większości środowisk, prawdopodobnie można go przeoczyć. Jednak w razie potrzeby (w niektórych przypadkach skrajnych) ten problem można złagodzić za pomocą nieco bardziej złożonego przykładu:
EDYCJA: Utwórz
isDirectory()
funkcję. Usuń rzeczywisty katalog na końcu. Napraw brakującą rekurencję.źródło
await
na własnąPromise.all(…)
; czy to celowe? Wygląda na to, że w obecnym stanieresults.forEach
iterowałby nad obietnicami, podczas gdy kod oczekuje iteracji nad wynikami. Czy coś brakuje?if (!fs.existsSync(dir)) return
readdir
wyrzuci błąd tak, jak powinien. Jeślirmdir non-existing-dir
kod wyjścia jest błędem. Próbowanie / łapanie byłoby obowiązkiem konsumenta. Jest to ta sama metoda, którą opisano w dokumentach węzła, jeśli chodzi o korzystanie z funkcji fs. Oczekują, że spróbujesz / złapiesz i spojrzysz na błędy,code
aby ustalić, co zrobić. Dodatkowa kontrola wprowadza warunek wyścigu.fs.exists
używana jest wersja synchroniczna . PS to świetne rozwiązanie.Oto asynchroniczna wersja odpowiedzi @ SharpCoder
źródło
Napisałem tę funkcję o nazwie remove folder. Rekurencyjnie usunie wszystkie pliki i foldery w lokalizacji. Jedyny wymagany pakiet to asynchronizacja.
źródło
Jeśli używasz węzła 8+, chcesz asynchroniczności i nie chcesz zewnętrznych zależności, oto wersja asynchroniczna / oczekująca:
źródło
Wersja asynchroniczna odpowiedzi @ SharpCoder przy użyciu fs.promises:
źródło
Dotarłem tutaj, próbując się z tym
gulp
pogodzić i piszę o dalszych zasięgach.gulp-clean
przestarzałe dlagulp-rimraf
gulp-rimraf
przestarzałe na rzeczdelete-files-folders
Jeśli chcesz usunąć pliki i foldery za pomocą
del
, powinieneś dołączyć/**
do usunięcia rekurencyjnego.źródło
Pakiet de facto jest
rimraf
, ale oto moja mała wersja asynchroniczna:źródło
W najnowszej wersji node.js (12.10.0 lub później), przy czym
rmdir
funkcje stylfs.rmdir()
,fs.rmdirSync()
ifs.promises.rmdir()
mają nową opcję eksperymentalnyrecursive
, który umożliwia usunięcie niepuste katalogi, npPowiązany PR na GitHub: https://github.com/nodejs/node/pull/29168
źródło
Zgodnie z
fs
dokumentacją ,fsPromises
obecnie dajerecursive
opcję na zasadzie eksperymentu, który, przynajmniej w moim przypadku na Windows, usuwa katalog i wszystkie pliki w nim.Czy
recursive: true
usuwa pliki w systemie Linux i MacOS?źródło
Ultraszybka i odporna na awarie
Możesz użyć
lignator
pakietu ( https://www.npmjs.com/package/lignator ), jest szybszy niż jakikolwiek kod asynchroniczny (np. Rimraf) i bardziej odporny na awarie (szczególnie w systemie Windows, w którym usuwanie plików nie jest natychmiastowe, a pliki mogą być zablokowane przez inne procesy).źródło
Synchronizuj folder usuń z plikami lub tylko z plikiem.
Nie jestem dawcą ani współpracownikiem, ale nie mogłem znaleźć dobrego rozwiązania tego problemu i musiałem znaleźć swoją drogę ... więc mam nadzieję, że ci się spodoba :)
Działa idealnie dla mnie z dowolną liczbą zagnieżdżone katalogi i podkatalogi. Uwaga na zakres „tego” przy rekursywnej funkcji, twoja implementacja może być inna. W moim przypadku funkcja ta pozostaje w zwrocie innej funkcji, dlatego właśnie ją w ten sposób nazywam.
źródło
Chociaż
recursive
jest eksperymentalną opcjąfs.rmdir
źródło
Aktualizacja 2020
Od wersji 12.10.0 dodano opcję recursiveOption dla opcji.
Pamiętaj, że usuwanie rekurencyjne jest eksperymentalne .
Zrobiłbyś więc synchronizację:
lub asynchronicznie:
źródło
Wystarczy użyć modułu rmdir ! to łatwe i proste.
źródło
Inną alternatywą jest użycie
fs-promise
modułu, który zapewnia obiecane wersjefs-extra
modułówmożesz wtedy napisać jak w tym przykładzie:
Uwaga: async / await wymaga najnowszej wersji nodejs (7.6+)
źródło
Szybkim i brudnym sposobem (być może do testowania) może być bezpośrednie użycie metody
exec
lub wspawn
celu wywołania wywołania systemu operacyjnego w celu usunięcia katalogu. Przeczytaj więcej na temat procesu potomnego NodeJs .Minusy to:
Korzyści:
źródło
-f
flagę, aby być bezpiecznym lub upewnić się podczas pisania, że nie usunie wszystkiego.exec + rm
to poprawne i przydatne polecenie w węźle, którego często używam podczas testowania.Chciałbym, aby istniał sposób na to bez dodatkowych modułów dla czegoś tak małego i powszechnego, ale to jest najlepsze, co mogłem wymyślić.
Aktualizacja: powinien teraz działać w systemie Windows (testowany system Windows 10), a także powinien działać na systemach Linux / Unix / BSD / Mac.
źródło
child_process.execFile
który nie wywołuje powłoki, i zamiast tego przekazuj jawnie argumenty.Jest to jedno podejście wykorzystujące promisify i dwie funkcje pomocy (do i do wszystkich), aby rozwiązać obietnicę.
Wszystkie działania są asynchroniczne.
źródło
// bez użycia jakiejkolwiek biblioteki osób trzecich
źródło
fs.unllinkSync(path.join(FOLDER_PATH, element);
źródło