Entfernen Sie das nicht leere Verzeichnis


300

In meiner Knotenanwendung muss ich ein Verzeichnis entfernen, das einige Dateien enthält, aber fs.rmdirnur in leeren Verzeichnissen funktioniert. Wie kann ich das machen?


1
Kurz gesagt: fs.readdir(dirPath)Durchlaufen Sie für ein Array von Pfaden in einem Ordner die fs.unlink(filename)einzelnen Dateien und anschließend fs.rmdir(dirPath)den jetzt leeren Ordner. Wenn Sie rekursiv arbeiten müssen, überprüfen Sie fs.lstat(filename).isDirectory().
Iono

Antworten:


319

Hierfür gibt es ein Modul namens rimraf( https://npmjs.org/package/rimraf ). Es bietet die gleiche Funktionalität wierm -Rf

Asynchrone Verwendung:

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

Synchronisierungsnutzung :

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

1
Seltsam, ich habe noch nie so ein Verhalten gesehen. Ich würde vorschlagen, nach einem Fehler zu suchen und / oder ihn einzureichen. github.com/isaacs/rimraf/issues
Morgan ARR Allen

35
Dies ist mit NodeJS Core-Bibliotheken problemlos möglich. Warum sollte ein nicht gewartetes Paket eines Drittanbieters installiert werden?
SudoKid

4
@EmettSpeer Wann meinst du mit "leicht gemacht werden"? Selbst eine Funktion wie deleteFolderRecursivein der folgenden Antwort schreiben ?
Freilauf

23
"Aber selbst mit der folgenden Funktion ist es besser, Ihrem System ein nicht benötigtes Paket hinzuzufügen." Ich bin absolut anderer Meinung. Sie erfinden das Rad zum 19-millionsten Mal ohne Grund neu und riskieren dabei Fehler oder Sicherheitslücken. Zumindest ist es Zeitverschwendung. Inb4 "Was ist, wenn sie das Paket fallen lassen?": In dem äußerst unwahrscheinlichen Fall, dass das Paket aus der npm-Registrierung entfernt wird, können Sie es dann jederzeit durch Ihr eigenes ersetzen . Es macht keinen Sinn, den Kopf zu verbinden, bevor Sie ihn brechen.
Demonblack

3
Sie können jetzt eine recursiveOption verwenden: stackoverflow.com/a/57866165/6269864

245

Ordner synchron entfernen

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
Vielleicht möchten Sie einige Überprüfungen hinzufügen, um sicherzustellen, dass Sie dies nicht versehentlich auf '/' ausführen. Wenn Sie beispielsweise einen leeren Pfad und einen Tippfehler in der Datei übergeben, kann curPath das Stammverzeichnis sein.
Jake_Howard

10
Robustere Ausführung: ersetzen var curPath = path + "/" + file;mit var curPath = p.join(path, file);bereitgestellten enthalten Sie den Pfad - Modul:var p = require("path")
Andry

9
Windows hat \ Schrägstriche, path.join(dirpath, file)sollte also besser sein alspath + "/" + file
Thybzi

5
Bei diesem Code wird möglicherweise die maximale Größe des Aufrufstapels überschritten, da zu viele Vorgänge in einer Tick-Zeit ausgeführt wurden. @Walf Wenn Sie eine Konsolenanwendung ausführen, haben Sie 1 Client, nicht mehr. In diesem Fall muss
Async

4
Ich erhalte 'Fehler: ENOTEMPTY: Verzeichnis nicht leer'
Seagull

168

Die meisten fsBenutzer von Node.js möchten Funktionen, die der "Unix-Methode" für den Umgang mit Dateien nahe kommen. Ich benutze fs-extra , um all die coolen Sachen zu bringen:

fs-extra enthält Methoden, die nicht im Paket vanilla Node.js fs enthalten sind. Wie mkdir -p, cp -r und rm -rf.

Noch besser ist, dass fs-extra ein Ersatz für native fs ist. Alle Methoden in fs sind unverändert und damit verbunden. Dies bedeutet, dass Sie fs durch fs-extra ersetzen können :

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

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

Und dann können Sie einen Ordner folgendermaßen entfernen:

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

für die Synchronisierungsversion, die Sie benötigenremoveSync('/tmp/myFolder')
olidem

148

Ab 2019 ...

Ab Node.js 12.10.0 , fs.rmdirSyncunterstützt eine recursiveAuswahl, so dass Sie schließlich tun können:

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

Wobei die recursiveOption das gesamte Verzeichnis rekursiv löscht.


5
@anneb Dies passiert, wenn Sie eine ältere Version von Node.js (<12.10) verwenden. Die neueste Version erkennt die Option recursive: trueund löscht nicht leere Ordner ohne Beanstandung.
GOTO 0

9
Das rekursive Entfernen ist ab Knoten v13.0.1
Tim

5
Funktionssignatur ist tatsächlich fs.rmdir(path[, options], callback)oderfs.rmdirSync(path[, options])
conceptdeluxe

@ Tim was meinst du mit experimentell?
Emerica

2
@Emerica In den offiziellen Dokumenten von node.js gibt es eine große orangefarbene Benachrichtigung, die besagt, dass fs.rmdirexperimentell mit Stabilität 1 gearbeitet wird. "Stabilität: 1 - experimentell. Die Funktion unterliegt nicht den Regeln für die semantische Versionierung. In keinem Fall können nicht abwärtskompatible Änderungen oder Entfernungen auftreten zukünftige Version. Die Verwendung der Funktion wird in Produktionsumgebungen nicht empfohlen. "
Tim

24

Meine geänderte Antwort von @oconnecp ( https://stackoverflow.com/a/25069828/3027390 )

Verwendet path.join für eine bessere plattformübergreifende Erfahrung. Vergessen Sie also nicht, es zu verlangen.

var path = require('path');

Auch umbenannte Funktion in 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

Normalerweise belebe ich alte Fäden nicht wieder, aber hier gibt es eine Menge Abwanderung und ohne Rimraf-Antwort. Diese scheinen mir alle zu kompliziert.

Erstens können Sie im modernen Knoten (> = v8.0.0) den Prozess vereinfachen, indem Sie nur vollständig asynchrone Knotenkernmodule verwenden und gleichzeitig die Verknüpfung von Dateien in einer Funktion von fünf Zeilen parallelisieren und trotzdem die Lesbarkeit beibehalten:

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);
};

In einem anderen Punkt ist ein Schutz für Pfadüberquerungsangriffe für diese Funktion ungeeignet, weil

  1. Es liegt außerhalb des Geltungsbereichs des Grundsatzes der Einzelverantwortung .
  2. Sollte vom Anrufer nicht diese Funktion behandelt werden. Dies ist insofern mit der Befehlszeile vergleichbar rm -rf, als es ein Argument akzeptiert und es dem Benutzer ermöglicht, rm -rf /wenn er dazu aufgefordert wird. Es liegt in der Verantwortung eines Skripts, nicht das rmProgramm selbst zu schützen .
  3. Diese Funktion kann einen solchen Angriff nicht bestimmen, da sie keinen Referenzrahmen hat. Dies liegt wiederum in der Verantwortung des Anrufers, der den Absichtskontext haben würde, der ihm eine Referenz zum Vergleichen der Pfadüberquerung liefern würde.
  4. Sym-Links sind kein Problem , wie .isDirectory()ist falsefür sym-Links und UNLINKED nicht rekursiv.

Last but not least gibt es eine seltene Race-Bedingung, dass die Rekursion fehlerhaft sein kann, wenn einer der Einträge nicht verknüpft oder gelöscht wurde außerhalb dieses Skripts zum richtigen Zeitpunkt während der Ausführung dieser Rekursion nicht . Da dieses Szenario in den meisten Umgebungen nicht typisch ist, kann es wahrscheinlich übersehen werden. Bei Bedarf (für einige Randfälle) kann dieses Problem jedoch durch dieses etwas komplexere Beispiel behoben werden:

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);
};

BEARBEITEN: Machen Sie isDirectory()eine Funktion. Entfernen Sie das eigentliche Verzeichnis am Ende. Fehlende Rekursion behoben.


1
Dies ist eine wirklich nette Lösung. Frage zum zweiten Codebeispiel: Sie rufen awaitIhren nicht an Promise.all(…); ist das beabsichtigt? Es scheint, als results.forEachwürde der aktuelle Status Versprechungen durchlaufen, während der Code erwartet, dass er die Ergebnisse durchläuft. Vermisse ich etwas
Anton Strogonoff

@ Tony du bist richtig es ist ein Tippfehler / Bug. Guter Fang!
Sukima

Vielleicht zuerst überprüfen, ob das Verzeichnis existiert? so etwas wieif (!fs.existsSync(dir)) return
GTPV

@GTPV Warum? Dies erhöht die Verantwortung für diese Funktion. readdirwird einen Fehler auslösen, wie es sollte. Wenn Sie rmdir non-existing-dirden Exit-Code ist ein Fehler. Es liegt in der Verantwortung des Verbrauchers, es zu versuchen / zu fangen. Dies ist die gleiche Methode, die in den Node-Dokumenten beschrieben wird, wenn es um die Verwendung von fs-Funktionen geht. Sie erwarten, dass Sie versuchen / fangen und sich die Fehler ansehen, codeum festzustellen, was zu tun ist. Ein zusätzlicher Check führt eine Rennbedingung ein.
Sukima

Ich verstehe definitiv Ihren Standpunkt. Ich würde jedoch intuitiv erwarten, dass der Versuch, einen Ordner zu löschen, der nicht existiert, erfolgreich wäre, da er einfach nichts bewirken würde. Keine Rennbedingung, wenn die synchrone Version von fs.existsverwendet wird. PS das ist eine großartige Lösung.
GTPV

12

Hier ist eine asynchrone Version der Antwort von @ 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

Ich habe diese Funktion namens Ordner entfernen geschrieben. Es werden rekursiv alle Dateien und Ordner an einem Speicherort entfernt. Das einzige Paket, das benötigt wird, ist asynchron.

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
Die Idee ist eigentlich, keinen eigenen Code zu schreiben, wenn dieser bereits von jemand anderem geschrieben wurde. Der bessere Weg, dies zu tun, besteht darin, entweder rimraf oder fs-extra oder ein anderes Knotenmodul zu verwenden, um die Arbeit für Sie zu erledigen.
Victor Pudeyev

90
Ja, das Schreiben eines eigenen Codes ist schrecklich, da sich die Verwendung von Dutzenden von Modulen von Drittanbietern für relativ einfache Vorgänge in großen Anwendungen nie als nachteilig erwiesen hat.
Eric

8

Wenn Sie Knoten 8+ verwenden, möchten Sie Asynchronität und keine externen Abhängigkeiten. Hier ist die asynchrone / wartende Version:

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

Asynchrone Version der Antwort von @ SharpCoder mit 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

Ich erreichte hier, während ich versuchte, mit dem fertig zu werden, gulpund schreibe für weitere Reichweiten.

Wenn Sie Dateien und Ordner mit löschen möchten del, sollten Sie sie /**zum rekursiven Löschen anhängen .

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

2

Das De-facto-Paket ist rimraf, aber hier ist meine winzige asynchrone Version:

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

Laut fsDokumentation bietet fsPromisesderzeit die recursiveOption auf experimenteller Basis, die, zumindest in meinem Fall unter Windows, das Verzeichnis und alle darin enthaltenen Dateien entfernt.

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

Entfernt recursive: truedie Dateien unter Linux und MacOS?


1

Ultra-Geschwindigkeit und ausfallsicher

Sie können das lignatorPaket verwenden ( https://www.npmjs.com/package/lignator ), es ist schneller als jeder asynchrone Code (z. B. rimraf) und ausfallsicherer (insbesondere in Windows, wo das Entfernen von Dateien nicht sofort erfolgt und Dateien möglicherweise nicht vorhanden sind durch andere Prozesse gesperrt sein).

4,36 GB Daten, 28 042 Dateien, 4 217 Ordner unter Windows wurden in 15 Sekunden entfernt, während Rimrafs 60 Sekunden auf einer alten Festplatte lagen .

const lignator = require('lignator');

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

1

Ordner mit den Dateien oder nur einer Datei entfernen.

Ich bin weder ein Geber noch ein Mitwirkender, aber ich konnte keine gute Lösung für dieses Problem finden und musste mich zurechtfinden ... also hoffe ich, dass es Ihnen gefällt :)

Funktioniert perfekt für mich mit einer beliebigen Anzahl von verschachtelte Verzeichnisse und Unterverzeichnisse. Achtung für den Umfang von 'this' bei der Rekursion der Funktion kann Ihre Implementierung anders sein. In meinem Fall bleibt diese Funktion in der Rückgabe einer anderen Funktion, deshalb rufe ich sie damit auf.

    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

Während recursiveist eine experimentelle Option vonfs.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

2020 Update

Ab Version 12.10.0 recursiveOption für Optionen hinzugefügt.

Beachten Sie, dass das rekursive Löschen experimentell ist .

Sie würden also für die Synchronisierung Folgendes tun:

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

oder für Async:

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

0

Verwenden Sie einfach das rmdir-Modul ! es ist leicht und einfach.


6
Es ist nicht immer eine gute Idee, für jeden kleinen Code ein Modul zu verwenden. Wenn Sie beispielsweise eine Lizenzvereinbarung erstellen müssen, ist dies ein echtes Problem.
Mijago

4
Sie müssen ein Codebeispiel hinzufügen, damit Ihre Antwort interessanter wird
Xeltor

0

Eine andere Alternative ist die Verwendung des fs-promiseModuls, das vielversprechende Versionen des bereitstelltfs-extra Module

Sie könnten dann wie folgt schreiben:

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)

Hinweis: Für async / await ist eine aktuelle Version von nodejs (7.6+) erforderlich.


0

Ein schneller und schmutziger Weg (möglicherweise zum Testen) könnte darin bestehen, die Methode execoder direkt spawnzum Aufrufen des Betriebssystemaufrufs zum Entfernen des Verzeichnisses zu verwenden. Lesen Sie mehr über NodeJs child_process .

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

Nachteile sind:

  1. Sie sind abhängig vom zugrunde liegenden Betriebssystem, dh dieselbe Methode würde unter Unix / Linux ausgeführt, wahrscheinlich jedoch nicht unter Windows.
  2. Sie können den Prozess nicht unter Bedingungen oder Fehlern entführen. Sie geben die Aufgabe einfach dem zugrunde liegenden Betriebssystem und warten, bis der Exit-Code zurückgegeben wird.

Leistungen:

  1. Diese Prozesse können asynchron ausgeführt werden.
  2. Sie können auf die Ausgabe / den Fehler des Befehls warten, damit die Befehlsausgabe nicht verloren geht. Wenn der Vorgang nicht abgeschlossen ist, können Sie den Fehlercode überprüfen und erneut versuchen.

2
Perfekt, wenn Sie ein Skript schreiben und keine Abhängigkeiten installieren möchten, da Sie dieses Skript in 30 Sekunden löschen möchten, nachdem Sie alle Ihre Dateien gelöscht haben !!
Mathias

Es gibt immer Möglichkeiten, das Root-Dateisystem durcheinander zu bringen und zu löschen. In diesem Fall kann OP das -fFlag entfernen , um die Sicherheit zu gewährleisten, oder während der Eingabe sicherstellen, dass nicht alles gelöscht wird. exec + rmist ein gültiger und nützlicher Befehl im Knoten, den ich beim Testen häufig verwende.
Ausschlag

0

Ich wünschte, es gäbe eine Möglichkeit, dies ohne zusätzliche Module für etwas so Winziges und Gemeinsames zu tun, aber dies ist das Beste, was ich mir einfallen lassen könnte.

Update: Sollte jetzt unter Windows (getestet Windows 10) und auch unter Linux / Unix / BSD / Mac-Systemen funktionieren.

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);
    });
}

Vielleicht ist fs-extra der richtige Weg, wenn Sie ein einzelnes Modul möchten.
b01

3
Diese Methode ist geradezu gefährlich. Die Verkettung von Zeichenfolgen eines Shell-Befehls, insbesondere ohne Escapezeichen, führt zu Sicherheitslücken bei der Codeausführung und Ähnlichem. Wenn Sie rmdir verwenden möchten, verwenden Sie, child_process.execFiledas die Shell nicht aufruft, und übergeben Sie stattdessen explizit Argumente.
Nevyn

@nevyn Ich werde es versuchen und meine Antwort aktualisieren, wenn es funktioniert.
b01

Verwenden Sie immer lieber keine Dritten! Vielen Dank!
Anton Mitsev

Darüber hinaus ist diese Methode ziemlich langsam. Nodejs native API ist viel schneller.
Trikot

0

Dies ist ein Ansatz, bei dem promisify und zwei Hilfefunktionen (to und toAll) verwendet werden, um das Versprechen zu lösen.

Es führt alle Aktionen asynchron aus.

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

// ohne Verwendung einer Drittanbieter-Bibliothek

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
Dies wird für das funktionieren, was ich brauche, aber Sie möchten vielleicht den Pfad verwenden, anstatt den Schrägstrich zu verketten: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
Ich denke, so etwas sollte für verschachtelte Verzeichnisse funktionieren.
narr4jesus

Ja, sowohl für verschachtelte als auch für nicht verschachtelte Verzeichnisse
Erisan Olasheni
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.