Hapus direktori yang tidak kosong

300

Dalam aplikasi Node saya, saya perlu menghapus direktori yang memiliki beberapa file, tetapi fs.rmdirhanya berfungsi pada direktori kosong. Bagaimana saya bisa melakukan ini?

sachin
sumber
1
Singkatnya: fs.readdir(dirPath)untuk lintasan lintasan dalam folder, beralihlah fs.unlink(filename)untuk menghapus setiap file, dan akhirnya fs.rmdir(dirPath)menghapus folder yang sekarang kosong. Jika Anda perlu kambuh, periksa fs.lstat(filename).isDirectory().
iono

Jawaban:

319

Ada modul untuk ini yang disebut rimraf( https://npmjs.org/package/rimraf ). Ini menyediakan fungsi yang sama denganrm -Rf

Penggunaan Async :

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

Sinkronkan penggunaan:

rimraf.sync("/some/directory");
Morgan ARR Allen
sumber
1
Aneh, saya belum pernah melihat perilaku seperti itu. Saya sarankan mencari dan / atau mengajukan bug. github.com/isaacs/rimraf/issues
Morgan ARR Allen
35
Ini adalah sesuatu yang dapat dilakukan dengan mudah dengan NodeJS Core libs mengapa menginstal paket pihak ke-3 yang tidak terawat?
SudoKid
4
@EmettSpeer Kapan Anda maksud dengan "dilakukan dengan mudah"? Menulis fungsi sendiri seperti deleteFolderRecursivedalam jawaban berikut?
Freewind
23
"tetapi bahkan dengan fungsi di bawah ini lebih baik daripada menambahkan paket yang tidak dibutuhkan ke sistem Anda." Saya sangat tidak setuju. Anda menciptakan kembali roda untuk kali ke 19 juta tanpa alasan sama sekali, dan berisiko memperkenalkan bug atau kerentanan keamanan dalam proses. Setidaknya itu buang-buang waktu. Inb4 "bagaimana jika mereka menjatuhkan paket": dalam hal yang sangat tidak mungkin bahwa paket dihapus dari registri npm Anda selalu dapat menggantinya dengan milik Anda sendiri . Tidak ada gunanya membalut kepala Anda sebelum Anda mematahkannya.
Demonblack
3
Anda sekarang dapat menggunakan recursiveopsi: stackoverflow.com/a/57866165/6269864
245

Untuk menghapus folder secara sinkron

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);
  }
};
SharpCoder
sumber
33
Mungkin ingin menambahkan beberapa cek bahwa Anda tidak akan menjalankan ini secara tidak sengaja di '/'. Misalnya, melewati jalur kosong dan kesalahan ketik pada file dapat mengakibatkan curPath menjadi direktori root.
Jake_Howard
10
Implementasi yang lebih kuat: ganti var curPath = path + "/" + file;dengan var curPath = p.join(path, file);asalkan Anda menyertakan modul path:var p = require("path")
Andry
9
Windows memiliki \ slash, jadi path.join(dirpath, file)seharusnya lebih baik daripadapath + "/" + file
thybzi
5
Anda mungkin mendapatkan "Ukuran tumpukan panggilan maksimum terlampaui" dengan kode ini karena terlalu banyak operasi dalam satu waktu centang. @ Jika Anda menjalankan aplikasi konsol, Anda memiliki 1 klien, tidak lebih. Jadi, tidak perlu menggunakan async untuk aplikasi konsol dalam kasus ini
Leonid Dashko
4
Saya menerima 'Kesalahan: ENOTEMPTY: direktori not empty'
Seagull
168

Sebagian besar orang yang menggunakan fsNode.js ingin fungsi yang dekat dengan "cara Unix" berurusan dengan file. Saya menggunakan fs-extra untuk membawa semua barang keren:

fs-extra berisi metode yang tidak termasuk dalam paket fs vanilla Node.js. Seperti mkdir -p, cp -r, dan rm -rf.

Bahkan lebih baik, fs-extra adalah setetes pengganti fs asli. Semua metode dalam fs tidak dimodifikasi dan dilampirkan padanya. Ini berarti Anda dapat mengganti fs dengan fs-extra :

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

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

Dan kemudian Anda dapat menghapus folder dengan cara ini:

fs.removeSync('/tmp/myFolder'); 
//or
fs.remove('/tmp/myFolder', callback);
Pierre Maoui
sumber
untuk versi sinkronisasi yang Anda butuhkanremoveSync('/tmp/myFolder')
olidem
148

Pada 2019 ...

Pada Node.js 12.10.0 , fs.rmdirSyncmendukung recursiveopsi, sehingga Anda akhirnya dapat melakukan:

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

Di mana recursiveopsi menghapus seluruh direktori secara rekursif.

K - Toksisitas dalam SO meningkat.
sumber
5
@anneb Itu terjadi jika Anda menggunakan versi Node.js yang lebih lama (<12.10). Versi terbaru mengenali opsi recursive: truedan menghapus folder yang tidak kosong tanpa keluhan.
GOTO 0
9
Penghapusan rekursif masih eksperimental pada simpul v13.0.1
Tim
5
Fungsi tanda tangan sebenarnya fs.rmdir(path[, options], callback)ataufs.rmdirSync(path[, options])
conceptdeluxe
@Tim, apa yang Anda maksud dengan eksperimen?
Emerica
2
@Emerica Dalam dokumen resmi node.js ada pemberitahuan oranye besar yang mengatakan fs.rmdireksperimental dengan stabilitas 1. "Stabilitas: 1 - Eksperimental. Fitur ini tidak tunduk pada aturan Semantic Versioning. Perubahan atau penghapusan yang tidak kompatibel mundur dapat terjadi pada setiap rilis mendatang. Penggunaan fitur ini tidak disarankan di lingkungan produksi. "
Tim
24

Jawaban saya yang dimodifikasi dari @oconnecp ( https://stackoverflow.com/a/25069828/3027390 )

Gunakan path.join untuk pengalaman lintas platform yang lebih baik. Jadi, jangan lupa untuk membutuhkannya.

var path = require('path');

Juga berganti fungsi menjadi 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);
    }
}
thybzi
sumber
17

Saya biasanya tidak menghidupkan kembali utas lama tetapi ada banyak churn di sini dan tanpa jawaban rimraf ini semua tampak terlalu rumit bagi saya.

Pertama di Node modern (> = v8.0.0) Anda dapat menyederhanakan proses hanya menggunakan modul inti simpul, sepenuhnya asinkron, dan memparalelkan penautan file secara bersamaan semua dalam fungsi lima baris dan masih dapat dibaca:

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

Pada catatan lain penjaga untuk serangan jalur traversal tidak sesuai untuk fungsi ini karena

  1. Ini di luar ruang lingkup berdasarkan Prinsip Tanggung Jawab Tunggal .
  2. Harus ditangani oleh pemanggil bukan fungsi ini. Ini mirip dengan baris perintah rm -rfyang membutuhkan argumen dan akan memungkinkan pengguna untuk rm -rf /jika diminta. Itu akan menjadi tanggung jawab naskah untuk menjaga bukan rmprogram itu sendiri.
  3. Fungsi ini tidak akan dapat menentukan serangan seperti itu karena tidak memiliki kerangka referensi. Sekali lagi itu adalah tanggung jawab penelepon yang akan memiliki konteks maksud yang akan memberikan referensi untuk membandingkan jalur traversal.
  4. Sym-link yang tidak perhatian seperti .isDirectory()ini falseuntuk sym-link dan dihapus linknya tidak recursed ke dalam.

Terakhir namun tidak kalah pentingnya, ada kondisi balapan yang jarang terjadi bahwa rekursi dapat kesalahan jika salah satu entri dibatalkan tautannya atau dihapus di luar skrip ini pada waktu yang tepat saat rekursi ini berjalan. Karena skenario ini tidak khas di sebagian besar lingkungan, kemungkinan besar hal itu dapat diabaikan. Namun, jika diperlukan (untuk beberapa kasus tepi) masalah ini dapat dikurangi dengan contoh yang sedikit lebih kompleks ini:

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

EDIT: Buat isDirectory()fungsi. Hapus direktori yang sebenarnya di bagian akhir. Perbaiki rekursi yang hilang.

Sukima
sumber
1
Ini adalah solusi yang sangat rapi. Pertanyaan tentang contoh kode kedua: Anda tidak menelepon awaitAnda Promise.all(…); Apakah ini disengaja? Sepertinya dalam kondisi saat ini results.forEachakan beralih lebih dari janji, sementara kode mengharapkan untuk beralih pada hasil. Apakah saya melewatkan sesuatu?
Anton Strogonoff
@Tony Anda benar itu salah ketik / bug. Tangkapan yang bagus!
Sukima
Mungkin cek pertama untuk memastikan direktori itu ada? sesuatu sepertiif (!fs.existsSync(dir)) return
GTPV
@ GTPV Kenapa? Ini meningkatkan tanggung jawab fungsi ini. readdirakan melempar kesalahan sebagaimana mestinya. Jika Anda rmdir non-existing-dirkode keluar adalah kesalahan. Ini akan menjadi tanggung jawab konsumen untuk mencoba / menangkap. Ini adalah metode yang sama dijelaskan dalam Node docs ketika datang untuk menggunakan fungsi fs. Mereka mengharapkan Anda untuk mencoba / menangkap dan melihat kesalahan codeuntuk menentukan apa yang harus dilakukan. Pemeriksaan tambahan menunjukkan kondisi balapan.
Sukima
Saya pasti mengerti maksud Anda. Namun saya berharap secara intuitif bahwa upaya untuk menghapus folder yang tidak ada akan berhasil karena ia tidak akan melakukan apa-apa. Tidak ada kondisi ras jika versi sinkron fs.existsdigunakan. PS ini adalah solusi bagus.
GTPV
12

Ini adalah versi async dari jawaban @ 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);
            });
        });
    });
};
Tony Brix
sumber
10

Saya menulis fungsi ini disebut hapus folder. Itu akan secara rekursif menghapus semua file dan folder di suatu lokasi. Satu-satunya paket yang diperlukan adalah async.

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)
            })
        })
    })
}
oconnecp
sumber
4
Idenya sebenarnya adalah untuk tidak menulis kode Anda sendiri jika sudah ditulis oleh orang lain. Cara yang lebih baik untuk melakukannya adalah menggunakan rimraf atau fs-extra atau modul simpul lainnya, untuk melakukan pekerjaan untuk Anda.
Victor Pudeyev
90
Ya, menulis kode Anda sendiri sangat buruk, karena menggunakan lusinan modul pihak ke-3 untuk operasi yang relatif sepele tidak pernah terbukti memiliki kelemahan dalam aplikasi skala besar.
Eric
8

Jika Anda menggunakan node 8+ ingin asyncronicity dan tidak ingin dependensi eksternal, berikut adalah versi async / menunggu:

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);
    }
}
RonZ
sumber
4

Versi async dari jawaban @ SharpCoder menggunakan 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);
    }
};
Kesalahan 404
sumber
3

Saya sampai di sini sambil mencoba untuk melupakan gulpdan saya menulis untuk mencapai lebih jauh.

Saat Anda ingin menghapus file dan folder menggunakan del, Anda harus menambahkan /**untuk penghapusan rekursif.

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

Paket de facto adalah rimraf, tetapi di sini adalah versi async kecil saya:

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))
}
clarkttfu
sumber
2

Menurut fsdokumentasi , fsPromisessaat ini menyediakan recursiveopsi berdasarkan percobaan, yang, setidaknya dalam kasus saya sendiri di Windows, menghapus direktori dan file apa pun di dalamnya.

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

Apakah recursive: truemenghapus file di Linux dan MacOS?

orang tua
sumber
1

Sangat cepat dan tahan gagal

Anda dapat menggunakan lignatorpaket ( https://www.npmjs.com/package/lignator ), lebih cepat daripada kode async (misalnya rimraf) dan lebih banyak bukti kegagalan (terutama di Windows, di mana penghapusan file tidak instan dan file mungkin dikunci oleh proses lain).

4,36 GB data, 28.042 file, 4 217 folder pada Windows dihapus dalam 15 detik vs rimraf 60 detik pada HDD lama.

const lignator = require('lignator');

lignator.remove('./build/');
HankMoody
sumber
1

Folder Sync dihapus dengan file atau hanya file.

Saya bukan pemberi atau kontributor tetapi saya tidak dapat menemukan solusi yang baik untuk masalah ini dan saya harus menemukan jalan saya ... jadi saya harap Anda akan menyukainya :)

Bekerja sempurna untuk saya dengan sejumlah direktori dan sub direktori bersarang. Perhatian untuk ruang lingkup 'ini' ketika berulang fungsi, implementasi Anda mungkin berbeda. Dalam kasus saya fungsi ini tetap menjadi pengembalian fungsi lain itu sebabnya saya menyebutnya dengan ini.

    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);
        }
MetaTron
sumber
1

Sementara recursivemerupakan opsi eksperimental darifs.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);
            });
        });
    });
}
Aikon Mogwai
sumber
1

Pembaruan 2020

Dari versi 12.10.0 rekursif Pilihan Pilihan telah ditambahkan untuk opsi.

Perhatikan bahwa penghapusan rekursif bersifat eksperimental .

Jadi yang akan Anda lakukan untuk sinkronisasi:

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

atau untuk async:

fs.rmdir(dir, {recursive: true});
Giovanni Patruno
sumber
0

Cukup gunakan modul rmdir ! itu mudah dan sederhana.

Aminovski
sumber
6
Tidak selalu merupakan ide yang baik untuk menggunakan modul untuk setiap bagian kecil kode. Jika Anda harus membuat perjanjian lisensi misalnya, ini menimbulkan rasa sakit yang nyata.
Mijago
4
Anda perlu menambahkan contoh kode agar jawaban Anda menjadi lebih menarik
Xeltor
0

Alternatif lain adalah menggunakan fs-promisemodul yang menyediakan versi promisified darifs-extra modul

Anda kemudian dapat menulis seperti contoh ini:

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)

note: async / await membutuhkan versi nodejs terbaru (7.6+)

Max Fichtelmann
sumber
0

Cara cepat dan kotor (mungkin untuk pengujian) bisa langsung menggunakan execatau spawnmetode untuk memanggil panggilan OS untuk menghapus direktori. Baca lebih lanjut tentang proses child_pro NodeJs .

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

Kerugiannya adalah:

  1. Anda tergantung pada OS yang mendasarinya yaitu metode yang sama akan berjalan di unix / linux tetapi mungkin tidak di windows.
  2. Anda tidak dapat membajak proses pada kondisi atau kesalahan. Anda cukup memberikan tugas ke OS yang mendasarinya dan menunggu kode keluar dikembalikan.

Manfaat:

  1. Proses-proses ini dapat berjalan secara tidak sinkron.
  2. Anda dapat mendengarkan output / kesalahan dari perintah, maka output perintah tidak hilang. Jika operasi tidak selesai, Anda dapat memeriksa kode kesalahan dan coba lagi.
Ruam
sumber
2
Sempurna untuk ketika Anda menulis skrip dan tidak ingin menginstal dependensi karena Anda akan menghapus skrip ini dalam 30 detik setelah Anda menghapus semua file Anda !!
Mathias
Selalu ada cara untuk mengacaukan dan menghapus sistem file root. Dalam hal ini OP dapat menghapus -fbendera agar aman, atau memastikan saat mengetik bahwa ia tidak akan menghapus semuanya. exec + rmadalah perintah yang valid dan berguna dalam simpul yang sering saya gunakan selama pengujian.
Rash
0

Saya berharap ada cara untuk melakukan ini tanpa modul tambahan untuk sesuatu yang sangat kecil dan umum, tetapi ini adalah yang terbaik yang bisa saya lakukan.

Pembaruan: Sekarang seharusnya bekerja pada Windows (diuji Windows 10), dan juga harus bekerja pada sistem 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);
    });
}
b01
sumber
Mungkin fs-extra adalah cara untuk pergi jika Anda menginginkan satu modul.
B01
3
Metode ini benar-benar berbahaya. Rangkaian string dari perintah shell, terutama tanpa melarikan diri, mengundang kerentanan eksekusi kode dan sejenisnya. Jika Anda akan menggunakan rmdir, gunakan child_process.execFileyang tidak memanggil shell, dan berikan argumen secara eksplisit.
nevyn
@nevyn Saya akan mencobanya dan memperbarui jawaban saya jika berfungsi.
B01
Selalu lebih suka untuk tidak menggunakan pihak ketiga! Terima kasih!
Anton Mitsev
Selain itu, metode ini cukup lambat. Api asli Nodejs jauh lebih cepat.
mersey
0

Ini adalah satu pendekatan menggunakan fungsi promisify dan dua bantuan (ke dan untuk Semua) untuk menyelesaikan janji.

Itu semua tindakan asynchrounous.

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)
    }
}; 
Aecio Levy
sumber
0

// tanpa menggunakan lib pihak ketiga

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);
Amy
sumber
1
Ini akan bekerja untuk apa yang saya butuhkan, tetapi Anda mungkin ingin menggunakan path daripada menyatukan 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!')
  }
}
Erisan Olasheni
sumber
1
Saya pikir sesuatu seperti ini harus berfungsi untuk direktori bersarang.
fool4jesus
Ya, baik untuk direktori bersarang dan yang tidak bersarang
Erisan Olasheni