Yanıtlar:
Bunun için bir modül var rimraf
( https://npmjs.org/package/rimraf ). İle aynı işlevselliği sağlarrm -Rf
Zaman uyumsuz kullanım:
var rimraf = require("rimraf");
rimraf("/some/directory", function () { console.log("done"); });
Senkronizasyon kullanımı:
rimraf.sync("/some/directory");
deleteFolderRecursive
Aşağıdaki cevap gibi bir işlevi kendi kendine yazma ?
recursive
seçenek kullanabilirsiniz : stackoverflow.com/a/57866165/6269864
Klasörü eşzamanlı olarak kaldırmak için
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);
}
};
var curPath = path + "/" + file;
ile var curPath = p.join(path, file);
sağlanan Eğer yol modülünü dahil:var p = require("path")
path.join(dirpath, file)
daha iyi olmalıpath + "/" + file
fs
Node.js kullanan kişilerin çoğu, dosyalarla başa çıkmanın "Unix yoluna" yakın işlevler ister. Tüm harika şeyleri getirmek için fs-extra kullanıyorum :
fs-extra, vanilya Node.js fs paketine dahil olmayan yöntemleri içerir. Mkdir -p, cp -r ve rm -rf gibi.
Daha da iyisi, fs-extra , yerel f'lerin yerine bir damladır. Fs içindeki tüm yöntemler değiştirilmez ve ona eklenir. Bu, fs'yi fs-extra ile değiştirebileceğiniz anlamına gelir :
// this can be replaced
const fs = require('fs')
// by this
const fs = require('fs-extra')
Ve sonra bir klasörü şu şekilde kaldırabilirsiniz:
fs.removeSync('/tmp/myFolder');
//or
fs.remove('/tmp/myFolder', callback);
removeSync('/tmp/myFolder')
İtibariyle node.js 12.10.0 , fs.rmdirSync
bir destekler recursive
nihayet bunu yapabilirsiniz seçenekleri:
fs.rmdirSync(dir, { recursive: true });
Nerede recursive
seçenek yinelemeli dizinin tamamını siler.
recursive: true
ve boş klasörleri şikayet etmeden siler.
fs.rmdir(path[, options], callback)
veyafs.rmdirSync(path[, options])
fs.rmdir
, kararlılık 1 ile deneysel olduğunu söyleyen büyük bir turuncu bildirim var . "Kararlılık: 1 - Deneysel. Özellik Semantik Sürüm Oluşturma kurallarına tabi değildir. Gelecek sürüm. Bu özelliğin üretim ortamlarında kullanılması önerilmez. "
@Oconnecp adresinden değiştirilmiş yanıtım ( https://stackoverflow.com/a/25069828/3027390 )
Daha iyi platformlar arası deneyim için path.join öğesini kullanır. Yani, bunu zorunlu tutmayı unutmayın.
var path = require('path');
Ayrıca rimraf
;) işlevini yeniden adlandırdı
/**
* 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);
}
}
Genellikle eski iplikleri diriltmiyorum ama burada karmaşanın üzerinde çok şey var ve rimraf cevabı bu hepsi benim için çok karmaşık görünüyor.
Öncelikle modern Düğümde (> = v8.0.0), yalnızca tamamen eşzamanlı olmayan, yalnızca düğüm çekirdek modülleri kullanarak işlemi basitleştirebilir ve dosyaların bağlantılarını aynı anda beş satırlık bir işlevle paralel hale getirebilir ve yine de okunabilirliği sağlayabilirsiniz:
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);
};
Başka bir notta, yol geçiş saldırıları için bir koruma bu işlev için uygun değildir, çünkü
rm -rf
bir argüman alması ve rm -rf /
istenirse kullanıcıya izin vermesi için komut satırına benzer . rm
Programın kendisini korumak bir betiğin sorumluluğundadır ..isDirectory()
olduğunu false
sim-bağlantılar için ve içine recursed değil bağlantı kaldırıldı.Son fakat aynı derecede önemli olarak, kayıtlardan biri bu komut dosyası dışında , bu özyineleme çalışırken doğru zamanda kaldırılırsa, özyinelemenin hata verebileceği nadir bir yarış durumu vardır . Bu senaryo çoğu ortamda tipik olmadığından, gözden kaçırılabilir. Ancak, gerekirse (bazı uç durumlar için) bu sorun biraz daha karmaşık bir örnekle azaltılabilir:
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);
};
DÜZENLEME: Make isDirectory()
bir işlev. Sondaki asıl dizini kaldırın. Eksik özyineleme düzeltildi.
await
üzerinde senin Promise.all(…)
; bu kasıtlı mı? results.forEach
Kod, sonuçlar üzerinde yinelemeyi beklerken , mevcut durumunda vaatler üzerinde yinelenecek gibi görünüyor . Bir şey mi kaçırıyorum?
if (!fs.existsSync(dir)) return
readdir
gerektiği gibi bir hata atar. Eğer rmdir non-existing-dir
çıkış kodu bir hatadır. Yakalamaya çalışmak tüketicinin sorumluluğundadır. Bu, fs işlevlerini kullanma konusunda Düğüm belgelerinde açıklananla aynı yöntemdir. Ne yapmanız gerektiğini code
belirlemek için hata yakalamaya çalışmanızı / yakalamanızı beklerler . Ekstra bir kontrol bir yarış koşulu getirir.
fs.exists
kullanılırsa yarış durumu olmaz . PS bu harika bir çözüm.
İşte @ SharpCoder yanıtının eşzamansız bir sürümü
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);
});
});
});
};
Klasörü kaldır adlı bu işlevi yazdım. Bir konumdaki tüm dosya ve klasörleri özyinelemeli olarak kaldıracaktır. Gereken tek paket zaman uyumsuzdur.
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)
})
})
})
}
8+ düğümü kullanıyorsanız eşzamansızlık istiyor ve harici bağımlılıklar istemiyorsanız, eşzamansız / beklemede sürüm:
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);
}
}
@ SharpCoder'ın fs.promises kullanarak yanıtının zaman uyumsuz sürümü :
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);
}
};
Buraya ulaşmaya çalışırken ulaştım ve daha fazla erişim gulp
için yazıyorum.
gulp-clean
için kullanımdan kaldırıldı gulp-rimraf
gulp-rimraf
lehine itiraz delete-files-folders
Düğmesini kullanarak dosya ve klasörleri silmek istediğinizde del
, /**
yinelemeli silme işlemine eklemeniz gerekir .
gulp.task('clean', function () {
return del(['some/path/to/delete/**']);
});
De facto paketi rimraf
, ama işte benim küçük eşzamansız sürüm:
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))
}
Node.js son sürümüne (daha sonra 12.10.0 veya) olarak, rmdir
stil fonksiyonları fs.rmdir()
, fs.rmdirSync()
ve fs.promises.rmdir()
yeni bir deneysel seçenek var recursive
boş olmayan dizinleri silme sağlar, örneğin
fs.rmdir(path, { recursive: true });
GitHub'daki ilgili halkla ilişkiler: https://github.com/nodejs/node/pull/29168
fs
Belgelere göre , fsPromises
şu anda recursive
, en azından Windows'taki kendi durumumda, dizini ve içindeki dosyaları kaldıran deneysel bir seçenek sunuyor.
fsPromises.rmdir(path, {
recursive: true
})
recursive: true
Linux ve MacOS'taki dosyalar kaldırılıyor mu ?
Ultra hızlı ve hatasız
lignator
Paketi ( https://www.npmjs.com/package/lignator ) kullanabilirsiniz, herhangi bir zaman uyumsuz koddan (örn. Rimraf) daha hızlıdır ve daha fazla hataya dayanıklıdır (özellikle dosya kaldırma işleminin anlık olmadığı ve dosyaların olabileceği Windows'da) diğer işlemler tarafından kilitlenmelidir).
4,36 GB veri, 28 042 dosya, Windows'ta 4 217 klasör 15 saniyede kaldırıldı, rimrafın eski HDD'de 60 saniyesi .
const lignator = require('lignator');
lignator.remove('./build/');
Senkronizasyon klasörü dosyaları veya sadece bir dosya ile kaldırın.
Ben bir verici ya da bir katılımcı değilim ama bu sorunun iyi bir çözüm bulamadım ve yolumu bulmak zorundaydı ... bu yüzden umarım hoşuna gidecek :)
Herhangi bir sayıda benim için mükemmel çalışır yuvalanmış dizinler ve alt dizinler. İşlevi tekrarlarken 'this' kapsamına dikkat edin, uygulamanız farklı olabilir. Benim durumumda bu işlev başka bir işlevin geri dönüşüne kalır, bu yüzden onu bu şekilde çağırıyorum.
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);
}
İken recursive
deneysel bir seçenektirfs.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);
});
});
});
}
2020 Güncellemesi
Sürüm 12.10.0'dan itibaren recursiveOption seçenekler için eklendi.
Yinelemeli silme işleminin deneysel olduğunu unutmayın .
Yani senkronizasyon için yapardınız:
fs.rmdirSync(dir, {recursive: true});
veya zaman uyumsuzluk için:
fs.rmdir(dir, {recursive: true});
Sadece rmdir modülünü kullanın ! kolay ve basit.
Başka bir alternatif, modüllerin fs-promise
vaat edilmiş versiyonlarını sağlayan modülü kullanmaktırfs-extra
daha sonra bu örnek gibi yazabilirsiniz:
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)
not: async / await son bir nodejs sürümü gerektirir (7.6+)
Hızlı ve kirli bir yol (belki de test için) doğrudan dizini kaldırmak için OS çağrısını çağırmak için exec
veya spawn
yöntemini kullanmak olabilir . NodeJs child_process hakkında daha fazla bilgi edinin .
let exec = require('child_process').exec
exec('rm -Rf /tmp/*.zip', callback)
Dezavantajları:
Yararları:
-f
güvenli olması için bayrağı kaldırabilir veya yazarken her şeyi silmeyeceğinden emin olabilir. exec + rm
sınama sırasında sık kullandığım düğümde geçerli ve kullanışlı bir komuttur.
Keşke çok ufak ve yaygın bir şey için ek modüller olmadan bunu yapmanın bir yolu olsaydı, ama bu gelebileceğim en iyisi.
Güncelleme: Şimdi Windows üzerinde çalışmalı (test edilmiş Windows 10) ve Linux / Unix / BSD / Mac sistemlerinde de çalışmalıdır.
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);
});
}
child_process.execFile
, kabuğu çağırmayanları kullanın ve bunun yerine bağımsız değişkenleri açıkça geçirin.
Promisify kullanan bir yaklaşım ve vaadi çözmek için iki yardım fonksiyonu (to to to All).
Tüm eylemleri eşzamansız yapar.
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)
}
};
// herhangi bir üçüncü taraf lib kullanmadan
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);
fs.unllinkSync(path.join(FOLDER_PATH, element);
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!')
}
}
fs.readdir(dirPath)
bir klasördeki bir dizi yol için,fs.unlink(filename)
her dosyayı silmek ve sonrafs.rmdir(dirPath)
da şimdi boş olan klasörü silmek için tekrarlayın . Dinlemeniz gerekiyorsa kontrol edinfs.lstat(filename).isDirectory()
.