Usuń katalog, który nie jest pusty


298

W mojej aplikacji Node muszę usunąć katalog, który zawiera niektóre pliki, ale fs.rmdirdziała tylko w pustych katalogach. W jaki sposób mogę to zrobić?


1
W skrócie: 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().
— iono

Odpowiedzi:


319

Jest do tego moduł o nazwie rimraf( https://npmjs.org/package/rimraf ). Zapewnia taką samą funkcjonalność jakrm -Rf

Wykorzystanie asynchroniczne :

var rimraf = require("rimraf");
rimraf("/some/directory", function () { console.log("done"); });

Wykorzystanie synchronizacji :

rimraf.sync("/some/directory");

1
Dziwne, nigdy nie widziałem takiego zachowania. Sugeruję poszukiwanie i / lub zgłoszenie błędu. github.com/isaacs/rimraf/issues
— Morgan ARR Allen

35
Jest to coś, co można łatwo zrobić za pomocą bibliotek NodeJS Core, po co instalować nieobsługiwany pakiet innej firmy?
— SudoKid

4
@EmettSpeer Kiedy rozumiesz pojęcie „łatwo zrobić”? Samo pisanie funkcji jak deleteFolderRecursivew poniższej odpowiedzi?
— Freewind,

23
„ale nawet z funkcją poniżej jest lepsza niż dodanie niepotrzebnego pakietu do systemu.” Definitywnie się z tym nie zgadzam. Po raz kolejny wymyślasz koło po raz dziewiętnasty, zupełnie bez żadnego powodu, ryzykując wprowadzeniem błędów lub luk w zabezpieczeniach. Przynajmniej to strata czasu. Inb4 „co jeśli upuszczą pakiet”: w bardzo mało prawdopodobnym przypadku, gdy pakiet zostanie usunięty z rejestru npm, zawsze możesz go zastąpić własnym . Nie ma sensu bandażować głowy, zanim ją złamiesz.
— Demonblack

3
możesz teraz użyć recursiveopcji: stackoverflow.com/a/57866165/6269864

243

Aby usunąć folder synchronicznie

const fs = require('fs');
const Path = require('path');

const deleteFolderRecursive = function(path) {
  if (fs.existsSync(path)) {
    fs.readdirSync(path).forEach((file, index) => {
      const curPath = Path.join(path, file);
      if (fs.lstatSync(curPath).isDirectory()) { // recurse
        deleteFolderRecursive(curPath);
      } else { // delete file
        fs.unlinkSync(curPath);
      }
    });
    fs.rmdirSync(path);
  }
};

33
Może chcesz dodać kilka sprawdzeń, że nie zamierzasz przypadkowo uruchomić tego na '/'. Na przykład przekazanie pustej ścieżki i literówki w pliku może spowodować, że curPath będzie katalogiem głównym.
— Jake_Howard

9
Bardziej wytrzymałe wykonanie: wymienić var curPath = path + "/" + file;z var curPath = p.join(path, file);warunkiem, że zawiera moduł ścieżki:var p = require("path")
— Andry

9
Windows ma \ ukośniki, więc path.join(dirpath, file)powinno być lepiej niżpath + "/" + file
— thybzi

5
Możesz otrzymać „Przekroczono maksymalny rozmiar stosu wywołań” z tym kodem z powodu zbyt wielu operacji w jednym czasie zaznaczenia. @W połowie, jeśli uruchamiasz aplikację konsolową, masz 1 klienta, nie więcej. W tym przypadku nie ma potrzeby używania asynchronizacji aplikacji konsolowej
— Leonid Dashko

4
Otrzymuję komunikat „Błąd: ENOTEMPTY: katalog nie jest pusty”
— Mewa

168

Większość osób korzystających fsz Node.js chciałoby funkcji zbliżonych do „uniksowego sposobu” radzenia sobie z plikami. Korzystam z fs-extra, aby przynieść wszystkie fajne rzeczy:

fs-extra zawiera metody, które nie są zawarte w waniliowym pakiecie fs Node.js. Takich jak mkdir -p, cp -r i rm -rf.

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 :

// this can be replaced
const fs = require('fs')

// by this
const fs = require('fs-extra')

Następnie możesz usunąć folder w ten sposób:

fs.removeSync('/tmp/myFolder'); 
//or
fs.remove('/tmp/myFolder', callback);

dla potrzebnej wersji synchronizacjiremoveSync('/tmp/myFolder')
— olidem

148

Od 2019 roku ...

Począwszy od Node.js 12.10.0 , fs.rmdirSyncobsługuje recursiveopcje, dzięki czemu możesz w końcu wykonać:

fs.rmdirSync(dir, { recursive: true });

Gdzie recursiveopcja rekurencyjnie usuwa cały katalog.


5
@anneb Dzieje się tak, jeśli używasz starszej wersji Node.js (<12.10). Najnowsza wersja rozpoznaje tę opcję recursive: truei usuwa niepuste foldery bez reklamacji.
— GOTO 0

9
Usuwanie rekurencyjne jest nadal eksperymentalne od węzła v13.0.1
— Tim

5
Podpis funkcji jest faktycznie fs.rmdir(path[, options], callback)lubfs.rmdirSync(path[, options])
— conceptdeluxe

@Tim, co masz na myśli przez eksperymentalne?
— Emerica

2
@Emerica W oficjalnych dokumentach node.js znajduje się duże, pomarańczowe powiadomienie z informacją, że fs.rmdirjest 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 ”.
— Tim

24

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

var path = require('path');

Również przemianowano funkcję na rimraf;)

/**
 * Remove directory recursively
 * @param {string} dir_path
 * @see https://stackoverflow.com/a/42505874/3027390
 */
function rimraf(dir_path) {
    if (fs.existsSync(dir_path)) {
        fs.readdirSync(dir_path).forEach(function(entry) {
            var entry_path = path.join(dir_path, entry);
            if (fs.lstatSync(entry_path).isDirectory()) {
                rimraf(entry_path);
            } else {
                fs.unlinkSync(entry_path);
            }
        });
        fs.rmdirSync(dir_path);
    }
}

17

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ść:

const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const readdir = promisify(fs.readdir);
const rmdir = promisify(fs.rmdir);
const unlink = promisify(fs.unlink);

exports.rmdirs = async function rmdirs(dir) {
  let entries = await readdir(dir, { withFileTypes: true });
  await Promise.all(entries.map(entry => {
    let fullPath = path.join(dir, entry.name);
    return entry.isDirectory() ? rmdirs(fullPath) : unlink(fullPath);
  }));
  await rmdir(dir);
};

Z drugiej strony strażnik przed atakami z przejścia ścieżki jest nieodpowiedni dla tej funkcji, ponieważ

  1. Jest to poza zakresem oparte na zasadzie jednolitej odpowiedzialności .
  2. Powinien być obsługiwany przez dzwoniącego, a nie tę funkcję. Jest to podobne do wiersza poleceń 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ę rmsamego programu.
  3. Ta funkcja nie byłaby w stanie określić takiego ataku, ponieważ nie ma ram odniesienia. Ponownie jest to obowiązkiem dzwoniącego, który miałby kontekst intencji, który zapewniłby mu odniesienie do porównania przejścia ścieżki.
  4. Sym-linki nie są problemem, jak .isDirectory()to falsena 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:

exports.rmdirs = async function rmdirs(dir) {
  let entries = await readdir(dir, { withFileTypes: true });
  let results = await Promise.all(entries.map(entry => {
    let fullPath = path.join(dir, entry.name);
    let task = entry.isDirectory() ? rmdirs(fullPath) : unlink(fullPath);
    return task.catch(error => ({ error }));
  }));
  results.forEach(result => {
    // Ignore missing files/directories; bail on other errors
    if (result && result.error.code !== 'ENOENT') throw result.error;
  });
  await rmdir(dir);
};

EDYCJA: Utwórz isDirectory()funkcję. Usuń rzeczywisty katalog na końcu. Napraw brakującą rekurencję.


1
To naprawdę fajne rozwiązanie. Pytanie dotyczące drugiej próbki kodu: nie zadzwonić awaitna własną Promise.all(…); czy to celowe? Wygląda na to, że w obecnym stanie results.forEachiterowałby nad obietnicami, podczas gdy kod oczekuje iteracji nad wynikami. Czy coś brakuje?
— Anton Strogonoff

@ Tony masz rację, to jest literówka / błąd. Dobry chwyt!
— Sukima

Może najpierw sprawdzisz, czy katalog istnieje? coś w styluif (!fs.existsSync(dir)) return
— GTPV

@GTPV Dlaczego? Zwiększa to odpowiedzialność tej funkcji. readdirwyrzuci błąd tak, jak powinien. Jeśli rmdir non-existing-dirkod 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, codeaby ustalić, co zrobić. Dodatkowa kontrola wprowadza warunek wyścigu.
— Sukima,

Zdecydowanie rozumiem twój punkt widzenia. Spodziewałbym się jednak intuicyjnie, że próba usunięcia nieistniejącego folderu byłaby udana, ponieważ po prostu nic nie zrobiłaby. Brak warunków wyścigu, jeśli fs.existsużywana jest wersja synchroniczna . PS to świetne rozwiązanie.
— GTPV

12

Oto asynchroniczna wersja odpowiedzi @ SharpCoder

const fs = require('fs');
const path = require('path');

function deleteFile(dir, file) {
    return new Promise(function (resolve, reject) {
        var filePath = path.join(dir, file);
        fs.lstat(filePath, function (err, stats) {
            if (err) {
                return reject(err);
            }
            if (stats.isDirectory()) {
                resolve(deleteDirectory(filePath));
            } else {
                fs.unlink(filePath, function (err) {
                    if (err) {
                        return reject(err);
                    }
                    resolve();
                });
            }
        });
    });
};

function deleteDirectory(dir) {
    return new Promise(function (resolve, reject) {
        fs.access(dir, function (err) {
            if (err) {
                return reject(err);
            }
            fs.readdir(dir, function (err, files) {
                if (err) {
                    return reject(err);
                }
                Promise.all(files.map(function (file) {
                    return deleteFile(dir, file);
                })).then(function () {
                    fs.rmdir(dir, function (err) {
                        if (err) {
                            return reject(err);
                        }
                        resolve();
                    });
                }).catch(reject);
            });
        });
    });
};

10

Napisałem tę funkcję o nazwie remove folder. Rekurencyjnie usunie wszystkie pliki i foldery w lokalizacji. Jedyny wymagany pakiet to asynchronizacja.

var async = require('async');

function removeFolder(location, next) {
    fs.readdir(location, function (err, files) {
        async.each(files, function (file, cb) {
            file = location + '/' + file
            fs.stat(file, function (err, stat) {
                if (err) {
                    return cb(err);
                }
                if (stat.isDirectory()) {
                    removeFolder(file, cb);
                } else {
                    fs.unlink(file, function (err) {
                        if (err) {
                            return cb(err);
                        }
                        return cb();
                    })
                }
            })
        }, function (err) {
            if (err) return next(err)
            fs.rmdir(location, function (err) {
                return next(err)
            })
        })
    })
}

4
Chodzi o to, aby nie pisać własnego kodu, jeśli został już napisany przez kogoś innego. Lepszym sposobem na to jest skorzystanie z rimraf lub fs-extra lub dowolnego innego modułu węzła, aby wykonać pracę za Ciebie.
— Victor Pudeyev

90
Tak, pisanie własnego kodu jest okropne, ponieważ używanie dziesiątek modułów innych firm do stosunkowo trywialnych operacji nigdy nie wykazało żadnych wad w aplikacjach na dużą skalę.
— Eric

8

Jeśli używasz węzła 8+, chcesz asynchroniczności i nie chcesz zewnętrznych zależności, oto wersja asynchroniczna / oczekująca:

const path = require('path');
const fs = require('fs');
const util = require('util');

const readdir = util.promisify(fs.readdir);
const lstat = util.promisify(fs.lstat);
const unlink = util.promisify(fs.unlink);
const rmdir = util.promisify(fs.rmdir);

const removeDir = async (dir) => {
    try {
        const files = await readdir(dir);
        await Promise.all(files.map(async (file) => {
            try {
                const p = path.join(dir, file);
                const stat = await lstat(p);
                if (stat.isDirectory()) {
                    await removeDir(p);
                } else {
                    await unlink(p);
                    console.log(`Removed file ${p}`);
                }
            } catch (err) {
                console.error(err);
            }
        }))
        await rmdir(dir);
        console.log(`Removed dir ${dir}`);
    } catch (err) {
      console.error(err);
    }
}

4

Wersja asynchroniczna odpowiedzi @ SharpCoder przy użyciu fs.promises:

const fs = require('fs');
const afs = fs.promises;

const deleteFolderRecursive = async path =>  {
    if (fs.existsSync(path)) {
        for (let entry of await afs.readdir(path)) {
            const curPath = path + "/" + entry;
            if ((await afs.lstat(curPath)).isDirectory())
                await deleteFolderRecursive(curPath);
            else await afs.unlink(curPath);
        }
        await afs.rmdir(path);
    }
};

3

Dotarłem tutaj, próbując się z tym gulppogodzić i piszę o dalszych zasięgach.

Jeśli chcesz usunąć pliki i foldery za pomocą del, powinieneś dołączyć /**do usunięcia rekurencyjnego.

gulp.task('clean', function () {
    return del(['some/path/to/delete/**']);
});

2

Pakiet de facto jest rimraf, ale oto moja mała wersja asynchroniczna:

const fs = require('fs')
const path = require('path')
const Q = require('q')

function rmdir (dir) {
  return Q.nfcall(fs.access, dir, fs.constants.W_OK)
    .then(() => {
      return Q.nfcall(fs.readdir, dir)
        .then(files => files.reduce((pre, f) => pre.then(() => {
          var sub = path.join(dir, f)
          return Q.nfcall(fs.lstat, sub).then(stat => {
            if (stat.isDirectory()) return rmdir(sub)
            return Q.nfcall(fs.unlink, sub)
          })
        }), Q()))
    })
    .then(() => Q.nfcall(fs.rmdir, dir))
}


2

Zgodnie z fsdokumentacją , fsPromisesobecnie daje recursiveopcję na zasadzie eksperymentu, który, przynajmniej w moim przypadku na Windows, usuwa katalog i wszystkie pliki w nim.

fsPromises.rmdir(path, {
  recursive: true
})

Czy recursive: trueusuwa pliki w systemie Linux i MacOS?


1

Ultraszybka i odporna na awarie

Możesz użyć lignatorpakietu ( 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).

4,36 GB danych, 28 042 plików, 4 217 folderów w systemie Windows usuniętych w 15 sekund w porównaniu do 60 sekund rimrafa na starym dysku twardym.

const lignator = require('lignator');

lignator.remove('./build/');

1

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.

    const fs = require('fs');

    deleteFileOrDir(path, pathTemp = false){
            if (fs.existsSync(path)) {
                if (fs.lstatSync(path).isDirectory()) {
                    var files = fs.readdirSync(path);
                    if (!files.length) return fs.rmdirSync(path);
                    for (var file in files) {
                        var currentPath = path + "/" + files[file];
                        if (!fs.existsSync(currentPath)) continue;
                        if (fs.lstatSync(currentPath).isFile()) {
                            fs.unlinkSync(currentPath);
                            continue;
                        }
                        if (fs.lstatSync(currentPath).isDirectory() && !fs.readdirSync(currentPath).length) {
                            fs.rmdirSync(currentPath);
                        } else {
                            this.deleteFileOrDir(currentPath, path);
                        }
                    }
                    this.deleteFileOrDir(path);
                } else {
                    fs.unlinkSync(path);
                }
            }
            if (pathTemp) this.deleteFileOrDir(pathTemp);
        }

1

Chociaż recursivejest eksperymentalną opcjąfs.rmdir

function rm (path, cb) {
    fs.stat(path, function (err, stats) {
        if (err)
            return cb(err);

        if (stats.isFile())
            return fs.unlink(path, cb);

        fs.rmdir(path, function (err) {
            if (!err || err && err.code != 'ENOTEMPTY') 
                return cb(err);

            fs.readdir(path, function (err, files) {
                if (err)
                    return cb(err);

                let next = i => i == files.length ? 
                    rm(path, cb) : 
                    rm(path + '/' + files[i], err => err ? cb(err) : next(i + 1));

                next(0);
            });
        });
    });
}

1

Aktualizacja 2020

Od wersji 12.10.0 dodano opcję recursiveOption dla opcji.

Pamiętaj, że usuwanie rekurencyjne jest eksperymentalne .

Zrobiłbyś więc synchronizację:

fs.rmdirSync(dir, {recursive: true});

lub asynchronicznie:

fs.rmdir(dir, {recursive: true});

0

Wystarczy użyć modułu rmdir ! to łatwe i proste.


6
Nie zawsze dobrym pomysłem jest użycie modułu dla każdego małego fragmentu kodu. Jeśli na przykład musisz utworzyć umowę licencyjną, powoduje to prawdziwy ból.
— Mijago,

4
musisz dodać przykładowy kod, aby twoja odpowiedź była bardziej interesująca
— Xeltor

0

Inną alternatywą jest użycie fs-promisemodułu, który zapewnia obiecane wersje fs-extramodułów

możesz wtedy napisać jak w tym przykładzie:

const { remove, mkdirp, writeFile, readFile } = require('fs-promise')
const { join, dirname } = require('path')

async function createAndRemove() {
  const content = 'Hello World!'
  const root = join(__dirname, 'foo')
  const file = join(root, 'bar', 'baz', 'hello.txt')

  await mkdirp(dirname(file))
  await writeFile(file, content)
  console.log(await readFile(file, 'utf-8'))
  await remove(join(__dirname, 'foo'))
}

createAndRemove().catch(console.error)

Uwaga: async / await wymaga najnowszej wersji nodejs (7.6+)


0

Szybkim i brudnym sposobem (być może do testowania) może być bezpośrednie użycie metody execlub w spawncelu wywołania wywołania systemu operacyjnego w celu usunięcia katalogu. Przeczytaj więcej na temat procesu potomnego NodeJs .

let exec = require('child_process').exec
exec('rm -Rf /tmp/*.zip', callback)

Minusy to:

  1. Jesteś zależny od systemu operacyjnego, tzn. Ta sama metoda działałaby w systemie Unix / Linux, ale prawdopodobnie nie w systemie Windows.
  2. Nie możesz przejąć procesu z powodu błędów lub warunków. Po prostu powierz zadanie bazowemu systemowi operacyjnemu i poczekaj, aż kod wyjścia zostanie zwrócony.

Korzyści:

  1. Te procesy mogą działać asynchronicznie.
  2. Możesz nasłuchiwać danych wyjściowych / błędów polecenia, dlatego dane wyjściowe polecenia nie zostaną utracone. Jeśli operacja nie zostanie zakończona, możesz sprawdzić kod błędu i spróbować ponownie.

2
Idealne, gdy piszesz skrypt i nie chcesz instalować zależności, ponieważ masz zamiar usunąć ten skrypt w 30 sekund po usunięciu wszystkich plików !!
— Mathias

Zawsze są sposoby na zepsucie i usunięcie głównego systemu plików. W takim przypadku OP może usunąć -fflagę, aby być bezpiecznym lub upewnić się podczas pisania, że ​​nie usunie wszystkiego. exec + rmto poprawne i przydatne polecenie w węźle, którego często używam podczas testowania.
— Wysypka

0

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.

const
    execSync = require("child_process").execSync,
    fs = require("fs"),
    os = require("os");

let removeDirCmd, theDir;

removeDirCmd = os.platform() === 'win32' ? "rmdir /s /q " : "rm -rf ";

theDir = __dirname + "/../web-ui/css/";

// WARNING: Do not specify a single file as the windows rmdir command will error.
if (fs.existsSync(theDir)) {
    console.log(' removing the ' + theDir + ' directory.');
    execSync(removeDirCmd + '"' + theDir + '"', function (err) {
        console.log(err);
    });
}

Może fs-extra jest dobrym rozwiązaniem, jeśli chcesz mieć pojedynczy moduł.
— b01

3
Ta metoda jest wręcz niebezpieczna. Łączenie łańcuchowe polecenia powłoki, szczególnie bez ucieczki, zachęca do luk w wykonywaniu kodu i tym podobnych. Jeśli zamierzasz użyć rmdir, użyj, child_process.execFilektóry nie wywołuje powłoki, i zamiast tego przekazuj jawnie argumenty.
— Nevyn

@nevyn Spróbuję zaktualizować odpowiedź, jeśli zadziała.
— b01

Zawsze wolą nie korzystać z usług stron trzecich! Dzięki!
— Anton Mitsev,

Ponadto ta metoda jest dość powolna. Natywny interfejs API Nodejsa jest znacznie szybszy.
— mersey,

0

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.

const fs = require('fs');
const { promisify } = require('util');
const to = require('./to');
const toAll = require('./toAll');

const readDirAsync = promisify(fs.readdir);
const rmDirAsync = promisify(fs.rmdir);
const unlinkAsync = promisify(fs.unlink);

/**
    * @author Aécio Levy
    * @function removeDirWithFiles
    * @usage: remove dir with files
    * @param {String} path
    */
const removeDirWithFiles = async path => {
    try {
        const file = readDirAsync(path);
        const [error, files] = await to(file);
        if (error) {
            throw new Error(error)
        }
        const arrayUnlink = files.map((fileName) => {
            return unlinkAsync(`${path}/${fileName}`);
        });
        const [errorUnlink, filesUnlink] = await toAll(arrayUnlink);
        if (errorUnlink) {
            throw new Error(errorUnlink);
        }
        const deleteDir = rmDirAsync(path);
        const [errorDelete, result] = await to(deleteDir);
        if (errorDelete) {
            throw new Error(errorDelete);
        }
    } catch (err) {
        console.log(err)
    }
}; 

0

// bez użycia jakiejkolwiek biblioteki osób trzecich

const fs = require('fs');
var FOLDER_PATH = "./dirname";
var files = fs.readdirSync(FOLDER_PATH);
files.forEach(element => {
    fs.unlinkSync(FOLDER_PATH + "/" + element);
});
fs.rmdirSync(FOLDER_PATH);

1
To zadziała na to, czego potrzebuję, ale możesz chcieć użyć ścieżki zamiast łączenia slash:fs.unllinkSync(path.join(FOLDER_PATH, element);
— jackofallcode

-1
const fs = require("fs")
const path = require("path")

let _dirloc = '<path_do_the_directory>'

if (fs.existsSync(_dirloc)) {
  fs.readdir(path, (err, files) => {
    if (!err) {
      for (let file of files) {
        // Delete each file
        fs.unlinkSync(path.join(_dirloc, file))
      }
    }
  })
  // After the 'done' of each file delete,
  // Delete the directory itself.
  if (fs.unlinkSync(_dirloc)) {
    console.log('Directory has been deleted!')
  }
}

1
Myślę, że coś takiego powinno działać w zagnieżdżonych katalogach.
— fool4jesus

Tak, zarówno dla katalogu zagnieżdżonego, jak i katalogu nie zagnieżdżonego
— Erisan Olasheni
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.