私のNodeアプリケーションでは、いくつかのファイルを含むディレクトリを削除する必要がありますが、fs.rmdir
空のディレクトリでしか機能しません。これどうやってするの?
33 に答える
このためのモジュールがありますrimraf
( https://npmjs.org/package/rimraf )。と同じ機能を提供します。rm -Rf
非同期の使用:
var rimraf = require("rimraf");
rimraf("/some/directory", function () { console.log("done"); });
同期の使用:
rimraf.sync("/some/directory");
フォルダを同期的に削除するには
const fs = require('fs');
const Path = require('path');
const deleteFolderRecursive = function (directoryPath) {
if (fs.existsSync(directoryPath)) {
fs.readdirSync(directoryPath).forEach((file, index) => {
const curPath = path.join(directoryPath, file);
if (fs.lstatSync(curPath).isDirectory()) {
// recurse
deleteFolderRecursive(curPath);
} else {
// delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(directoryPath);
}
};
@oconnecp からの私の修正された回答 ( https://stackoverflow.com/a/25069828/3027390 )
クロスプラットフォーム エクスペリエンスを向上させるために path.join を使用します。したがって、それを要求することを忘れないでください。
var path = require('path');
また、関数の名前を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);
}
}
これは@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);
});
});
});
};
remove folder と呼ばれるこの関数を書きました。ある場所にあるすべてのファイルとフォルダーを再帰的に削除します。必要なパッケージは 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)
})
})
})
}
説明
Node.js v14 の時点で、require("fs").promises.rm
関数を使用して promise を使用してファイルを削除できるようになりました。最初の引数は、削除するファイルまたはフォルダーです (存在しないものでも)。2 番目の引数のオブジェクトでrecursive
およびオプションを使用して、オプションを使用したシェル コマンド ユーティリティの動作を模倣できます。force
rm
-rf
例
"use strict";
require("fs").promises.rm("directory", {recursive: true, force: true}).then(() => {
console.log("removed");
}).catch(error => {
console.error(error.message);
});
見る
を乗り越えようとしてここにたどり着きgulp
、さらなる到達のために書いています。
gulp-clean
非推奨gulp-rimraf
gulp-rimraf
を支持して非推奨delete-files-folders
を使用してファイルとフォルダーを削除する場合は、再帰的な削除del
を追加する必要があります。/**
gulp.task('clean', function () {
return del(['some/path/to/delete/**']);
});
fs
ドキュメントによると、fsPromises
現在recursive
、実験的にオプションを提供しています。これは、少なくとも Windows での私の場合、ディレクトリとその中のファイルを削除します。
fsPromises.rmdir(path, {
recursive: true
})
recursive: true
Linux と MacOS のファイルは削除されますか?
return new Promise((resolve, reject) => {
const fs = require("fs");
// directory path
const dir = "your/dir";
// delete directory recursively <------
fs.rmdir(dir, { recursive: true }, (err) => {
if (err) {
reject(err);
}
resolve(`${dir} is deleted!`);
});
});
rmdir モジュールを使用するだけです。それは簡単でシンプルです。
ファイルまたはファイルのみでフォルダーの削除を同期します。
私は寄付者でも貢献者でもありませんが、この問題の良い解決策を見つけることができず、自分の道を見つけなければなりませんでした...だから、あなたがそれを気に入ってくれることを願っています
:)ネストされたディレクトリとサブディレクトリ。関数を再帰するときの 'this' のスコープに注意してください。実装は異なる場合があります。私の場合、この関数は別の関数の戻りにとどまるため、これで呼び出しています。
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);
}
非常に小さくて一般的なものにモジュールを追加せずにこれを行う方法があればいいのにと思いますが、これが私が思いついた最高のものです。
更新: Windows (テスト済み Windows 10) で動作するようになり、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);
});
}
別の代替手段は、fs-promise
約束されたバージョンのモジュールを提供fs-extra
するモジュールを使用することです
次に、次の例のように記述できます。
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)
注: async/await には最新の nodejs バージョン (7.6+) が必要です
❄️ 使えますgraph-fs
directory.delete()