निर्देशिका निकालें जो खाली नहीं है


298

मेरे नोड एप्लिकेशन में मुझे एक निर्देशिका को हटाने की आवश्यकता है जिसमें कुछ फाइलें हैं, लेकिन fs.rmdirकेवल खाली निर्देशिकाओं पर काम करती है। मैं यह कैसे कर सकता हूँ?


1
संक्षेप में: fs.readdir(dirPath)किसी फ़ोल्डर में पथों की एक सरणी के लिए, fs.unlink(filename)प्रत्येक फ़ाइल को हटाने के लिए पुनरावृति करें , और फिर अंत fs.rmdir(dirPath)में अब खाली फ़ोल्डर को हटाने के लिए। यदि आपको पुनरावृत्ति करने की आवश्यकता है, तो जांच करें fs.lstat(filename).isDirectory()
आयनो

जवाबों:


319

इसके लिए एक मॉड्यूल है जिसे rimraf( https://npmjs.org/package/rimraf ) कहा जाता है । यह जैसी कार्यक्षमता प्रदान करता हैrm -Rf

Async उपयोग:

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

सिंक उपयोग:

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

1
अजीब बात है, मैंने ऐसा व्यवहार कभी नहीं देखा। मेरा सुझाव है कि बग की खोज करें और / या दाखिल करें। github.com/isaacs/rimraf/issues
मॉर्गन ARR एलन

35
यह एक ऐसी चीज है जिसे NodeJS कोर लिबास के साथ आसानी से किया जा सकता है क्यों एक अनमैटर्ड 3 पार्टी पैकेज स्थापित करें?
सूदकिद

4
@EmettSpeer आपके द्वारा "आसानी से किए जाने" का क्या मतलब है? deleteFolderRecursiveनिम्नलिखित उत्तर की तरह एक समारोह लेखन ?
Freewind

23
"लेकिन यहां तक ​​कि इसके बेहतर से नीचे के फंक्शन के साथ फिर आपके सिस्टम में एक अनावश्यक पैकेज जोड़ना।" मैं दृढ़ता से असहमत हूँ। आप बिना किसी कारण के 19 मिलियन समय के लिए पहिया को फिर से मजबूत कर रहे हैं, और इस प्रक्रिया में बग या सुरक्षा कमजोरियों का परिचय देते हुए जोखिम उठा रहे हैं। बहुत कम से कम यह समय की बर्बादी है। Inb4 "क्या होगा अगर वे पैकेज को छोड़ देते हैं": बेहद अप्रत्याशित घटना में पैकेज को npm रजिस्ट्री से हटा दिया जाता है जिसे आप हमेशा अपने स्वयं के साथ बदल सकते हैं इससे पहले कि आप इसे तोड़ते हैं, आपके सिर को पट्टी करने का कोई मतलब नहीं है।
डेमनब्लाक

3
अब आप एक recursiveविकल्प का उपयोग कर सकते हैं : stackoverflow.com/a/57866165/6269864

243

फ़ोल्डर को सिंक्रोनाइज़ करने के लिए

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
हो सकता है कि आप कुछ चेक जोड़ना चाहें जो आप गलती से '/' पर नहीं चलेंगे। उदाहरण के लिए, एक खाली पथ और फ़ाइल में एक टाइपो पारित होने के परिणामस्वरूप curPath को रूट dir किया जा सकता है।
जेक_हार्ड

9
और अधिक मजबूत कार्यान्वयन: की जगह var curPath = path + "/" + file;के साथ var curPath = p.join(path, file);प्रदान की आप पथ मॉड्यूल में शामिल हैं:var p = require("path")
एंड्री

9
विंडोज में स्लैश है, इसलिए इससे path.join(dirpath, file)बेहतर होना चाहिएpath + "/" + file
थिब्जी

5
एक टिक टाइम में बहुत सारे ऑपरेशन होने के कारण आपको इस कोड के साथ "अधिकतम कॉल स्टैक आकार को पार करना" पड़ सकता है। @ यदि आप कंसोल एप्लिकेशन चलाते हैं, तो आपके पास 1 क्लाइंट है, अधिक नहीं। तो, इस मामले में कंसोल ऐप के लिए एसिंक्स का उपयोग करने की आवश्यकता नहीं है
लियोनिद डैशको

4
मुझे 'त्रुटि: ENOTEMPTY: डायरेक्टरी खाली नहीं है'
सीगल

168

fsNode.js के साथ उपयोग करने वाले अधिकांश लोग फाइलों से निपटने के "यूनिक्स तरीके" के करीब कार्य करना चाहेंगे। मैं सभी अतिरिक्त सामान लाने के लिए fs-extra का उपयोग कर रहा हूं :

fs-extra में वेनिला Node.js fs पैकेज शामिल नहीं हैं। जैसे mkdir -p, cp -r, और rm -rf।

इससे भी बेहतर, एफएस-अतिरिक्त देशी एफएस के प्रतिस्थापन में एक बूंद है। एफएस में सभी विधियाँ अनमॉडिफाइड हैं और इससे जुड़ी हुई हैं। इसका अर्थ है कि आप fs को fs-extra द्वारा बदल सकते हैं :

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

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

और फिर आप इस तरह से एक फ़ोल्डर निकाल सकते हैं:

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

सिंक संस्करण के लिए आप की जरूरतremoveSync('/tmp/myFolder')
olidem

148

2019 तक ...

के रूप में Node.js 12.10.0 , fs.rmdirSyncएक का समर्थन करता है recursive, विकल्प तो आप अंत में कर सकते हैं:

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

जहां recursiveविकल्प पूरी निर्देशिका को पुनरावर्ती रूप से हटा देता है।


5
@anneb यह तब होता है जब आप Node.js (<12.10) के पुराने संस्करण का उपयोग कर रहे हैं। नवीनतम संस्करण विकल्प को पहचानता है recursive: trueऔर बिना शिकायत के गैर-खाली फ़ोल्डर को हटा देता है।
गोटो 0

9
रिकर्सिव रिमूवल अभी भी प्रायोगिक है क्योंकि नोड v13.0.1
टिम

5
समारोह हस्ताक्षर वास्तव में है fs.rmdir(path[, options], callback)याfs.rmdirSync(path[, options])
22

@ क्या आप प्रयोगात्मक से क्या मतलब है?
एमेरिका

2
@Emerica आधिकारिक नोड.जेएस डॉक्स में एक बड़ी नारंगी अधिसूचना है जो कह रही fs.rmdirहै कि स्थिरता 1 के साथ प्रयोगात्मक है। "स्थिरता: 1 - प्रायोगिक। यह सुविधा सिमेंटिक वर्जनिंग नियमों के अधीन नहीं है। गैर-पिछड़े संगत परिवर्तन या निष्कासन किसी भी स्थिति में हो सकता है। भविष्य का विमोचन। उत्पादन वातावरण में सुविधा का उपयोग अनुशंसित नहीं है। "
टिम

24

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

17

मैं आमतौर पर पुराने धागों को फिर से जीवित नहीं करता, लेकिन बहुत कुछ है यहाँ मंथन पर किया जा रहा है और रिम का जवाब है कि ये सब मुझे बहुत जटिल लगते हैं।

पहले आधुनिक नोड (> = v8.0.0) में आप केवल नोड कोर मॉड्यूल, पूरी तरह से अतुल्यकालिक का उपयोग करके प्रक्रिया को सरल कर सकते हैं, और सभी पंक्तियों के फंक्शनिंग को समकालिक रूप से पाँच पंक्तियों के फ़ंक्शन में समानांतर कर सकते हैं और फिर भी पठनीयता रख सकते हैं:

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

एक अन्य नोट पर पथ ट्रावल हमलों के लिए एक गार्ड इस फ़ंक्शन के लिए अनुचित है क्योंकि

  1. यह सिंगल रिस्पॉन्सिबिलिटी सिद्धांत के आधार पर दायरे से बाहर है
  2. फोन करने वाले द्वारा संभाला जाना चाहिए यह कार्य नहीं । यह कमांड-लाइन के लिए एक समान है rm -rfकि यह एक तर्क लेता है और उपयोगकर्ता को rm -rf /यह पूछने की अनुमति देगा । यह स्क्रिप्ट की जिम्मेदारी होगी कि वह rmकार्यक्रम की सुरक्षा न करे ।
  3. यह फ़ंक्शन इस तरह के हमले को निर्धारित करने में असमर्थ होगा क्योंकि इसमें संदर्भ का एक फ्रेम नहीं है। फिर से कॉल करने वाले की जिम्मेदारी होती है जो आशय का संदर्भ होता है जो इसे पथ-प्रदर्शक की तुलना करने के लिए एक संदर्भ प्रदान करता है।
  4. सिम-लिंक एक चिंता का विषय नहीं है जैसा .isDirectory()कि falseसिम्पल-लिंक के लिए होता है और इसे अनलिंक नहीं किया जाता है।

अंतिम लेकिन कम से कम, एक दुर्लभ दौड़ की स्थिति है कि पुनरावृत्ति त्रुटि कर सकती है यदि प्रविष्टियों में से एक को इस स्क्रिप्ट के बाहर अनलिंक किया गया या हटा दिया गया , जबकि यह पुनरावृत्ति चल रही है। चूंकि यह परिदृश्य अधिकांश वातावरणों में विशिष्ट नहीं है, इसलिए इसे अनदेखा किया जा सकता है। हालाँकि, यदि आवश्यक हो (कुछ किनारे के मामलों के लिए) इस मुद्दे को इस अधिक जटिल उदाहरण के साथ कम किया जा सकता है:

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

संपादित करें:isDirectory() एक फ़ंक्शन बनाएं । वास्तविक निर्देशिका को अंत में निकालें। लापता पुनरावृत्ति को ठीक करें।


1
यह वास्तव में साफ समाधान है। दूसरे कोड के नमूने के बारे में प्रश्न: आप awaitअपने फोन नहीं करते Promise.all(…); क्या यह जानबूझकर है? ऐसा लगता है कि इसकी वर्तमान स्थिति results.forEachवादों पर लागू होगी, जबकि कोड को परिणामों पर पुनरावृति की उम्मीद है। क्या मैं कुछ भूल रहा हूँ?
एंटोन स्ट्रोगोनॉफ

@ आप सही हैं यह एक टाइपो / बग है। अच्छी पकड़!
सुकिमा

शायद यह सुनिश्चित करने के लिए कि निर्देशिका मौजूद है पहले एक जाँच करें? कुछ इस तरहif (!fs.existsSync(dir)) return
GTPV

@GTPV क्यों? इससे इस फ़ंक्शन की जिम्मेदारी बढ़ जाती है। readdirके रूप में यह चाहिए एक त्रुटि फेंक देंगे। यदि आप rmdir non-existing-dirसे बाहर निकलें कोड एक त्रुटि है। कोशिश करना / पकड़ना उपभोक्ता की जिम्मेदारी होगी। यह एक ही विधि नोड डॉक्स में वर्णित है जब यह एफएस फ़ंक्शन का उपयोग करने की बात आती है। वे अपेक्षा करते हैं कि आप प्रयास करें / पकड़ें और त्रुटि codeको देखें कि क्या करना है। एक अतिरिक्त जांच एक दौड़ की स्थिति का परिचय देती है।
सुकिमा

मैं आपकी बात जरूर देखता हूं। मैं उम्मीद करता हूं कि हालांकि यह सहज रूप से है कि एक फ़ोल्डर को हटाने का प्रयास जो मौजूद नहीं है, सफल होगा क्योंकि यह बस कुछ नहीं करेगा। यदि कोई तुल्यकालिक संस्करण का fs.existsउपयोग किया जाता है तो कोई दौड़ की स्थिति नहीं । पुनश्च यह एक महान समाधान है।
GTPV

12

यहाँ @ SharpCoder के उत्तर का एक async संस्करण है

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

मैंने इस फ़ंक्शन को हटा दिया फ़ोल्डर कहा जाता है। यह एक स्थान पर सभी फ़ाइलों और फ़ोल्डरों को पुन: हटा देगा। केवल पैकेज की आवश्यकता है यह 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)
            })
        })
    })
}

4
विचार वास्तव में अपना स्वयं का कोड नहीं लिखना है यदि यह किसी और द्वारा पहले से लिखा गया है। इसे करने का बेहतर तरीका आपके लिए काम करने के लिए रिमरफ या एफएस-अतिरिक्त या किसी अन्य नोड मॉड्यूल का उपयोग करना है।
विक्टर पुडेयव

90
हाँ, अपना स्वयं का कोड लिखना बहुत ही भयानक है, क्योंकि अपेक्षाकृत तुच्छ कार्यों के लिए दर्जनों तीसरे मॉड्यूल का उपयोग करना कभी भी बड़े पैमाने पर अनुप्रयोगों में कोई कमियां साबित नहीं हुआ है।
एरिक

8

यदि आप नोड 8+ का उपयोग कर रहे हैं, तो आप असंगतता चाहते हैं और बाहरी निर्भरता नहीं चाहते हैं, तो यहां async / प्रतीक्षा संस्करण है:

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

Fs.promises का उपयोग करके @ SharpCoder के उत्तर का Async संस्करण :

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

मैं यहाँ तक पहुँचने की कोशिश कर gulpरहा था और मैं आगे तक पहुँचने के लिए लिख रहा हूँ।

जब आप फ़ाइलों और फ़ोल्डरों का उपयोग करके हटाना चाहते हैं del, तो आपको /**पुनरावर्ती विलोपन के लिए संलग्न करना चाहिए ।

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

2

वास्तव में डी पैकेज है rimraf, लेकिन यहां मेरा छोटा एस्किनेस संस्करण है:

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

Node.js का नवीनतम संस्करण (12.10.0 या बाद में) में, rmdirशैली कार्यों fs.rmdir(), fs.rmdirSync()है, और fs.promises.rmdir()एक नया प्रायोगिक विकल्प होता है recursiveगैर खाली निर्देशिका को हटाने की अनुमति देता है कि, जैसे

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

GitHub पर संबंधित PR: https://github.com/nodejs/node/pull/29168


2

fsप्रलेखन के अनुसार , fsPromisesवर्तमान में recursiveएक प्रयोगात्मक आधार पर विकल्प प्रदान करता है , जो कम से कम विंडोज पर मेरे खुद के मामले में, निर्देशिका और उसमें मौजूद किसी भी फाइल को हटा देता है।

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

करता है recursive: trueLinux और MacOS पर फ़ाइलों को हटा दें?


1

अल्ट्रा-स्पीड और फेल-प्रूफ

आप lignatorपैकेज ( https://www.npmjs.com/package/lignator ) का उपयोग कर सकते हैं , यह किसी भी async कोड (जैसे rimraf) से अधिक तेज है और अधिक विफल-प्रूफ (विशेष रूप से Windows में, जहां फ़ाइल निकालना तात्कालिक नहीं है और फ़ाइलें हो सकती हैं) अन्य प्रक्रियाओं द्वारा बंद किया जा सकता है)।

4,36 जीबी डेटा, 28 042 फाइलें, विंडोज पर 4 217 फ़ोल्डर्स 15 सेकंड में हटा दिए गए और पुराने HDD पर 60 सेकंड बनाम रिम्राफ

const lignator = require('lignator');

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

1

फ़ाइलों या केवल एक फ़ाइल के साथ सिंक फ़ोल्डर हटा दें।

मैं ज्यादा देने वाला नहीं हूं और न ही कोई योगदानकर्ता हूं लेकिन मुझे इस समस्या का अच्छा समाधान नहीं मिला और मुझे अपना रास्ता तलाशना पड़ा ... इसलिए मुझे उम्मीद है कि आप इसे पसंद करेंगे :)

मेरे लिए किसी भी संख्या के साथ काम करना सही होगा नेस्टेड निर्देशिका और उप निर्देशिका। फ़ंक्शन को दोहराते समय 'यह' के दायरे के लिए सावधानी, आपका कार्यान्वयन अलग हो सकता है। मेरे मामले में यह फ़ंक्शन किसी अन्य फ़ंक्शन की वापसी में रहता है, इसलिए मैं इसे इसके साथ बुला रहा हूं।

    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

जबकि recursiveएक प्रायोगिक विकल्प है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

2020 अद्यतन

संस्करण से 12.10.0 पुनरावर्ती विकल्प के लिए जोड़ा गया है।

ध्यान दें कि पुनरावर्ती विलोपन प्रयोगात्मक है

तो आप सिंक के लिए करेंगे:

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

या async के लिए:

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

0

बस rmdir मॉड्यूल का उपयोग करें ! यह आसान और सरल है।


6
कोड के हर छोटे टुकड़े के लिए मॉड्यूल का उपयोग करना हमेशा एक अच्छा विचार नहीं होता है। यदि आपको उदाहरण के लिए लाइसेंस अनुबंध बनाना है, तो यह एक वास्तविक दर्द उत्पन्न करता है।
मिजैगो

4
आपको अपने उत्तर के लिए एक कोड नमूना जोड़ने की आवश्यकता है जो अधिक दिलचस्प है
Xeltor

0

एक अन्य विकल्प 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 / प्रतीक्षा के लिए हाल ही के नोडज संस्करण की आवश्यकता है (7.6+)


0

एक त्वरित और गंदा तरीका (शायद परीक्षण के लिए) डायरेक्ट्री को हटाने के लिए ओएस कॉल को लागू करने के लिए सीधे execया spawnविधि का उपयोग कर सकता है । NodeJs child_process पर और पढ़ें ।

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

डाउनसाइड्स हैं:

  1. आप अंतर्निहित OS पर निर्भर होते हैं अर्थात एक ही विधि यूनिक्स / लिनक्स में चलेगी, लेकिन शायद विंडोज़ में नहीं।
  2. आप शर्तों या त्रुटियों पर प्रक्रिया को हाइजैक नहीं कर सकते। आप बस अंतर्निहित ओएस को कार्य देते हैं और निकास कोड के वापस आने का इंतजार करते हैं।

लाभ:

  1. ये प्रक्रियाएँ एसिंक्रोनस रूप से चल सकती हैं।
  2. आप कमांड के आउटपुट / त्रुटि के लिए सुन सकते हैं, इसलिए कमांड आउटपुट खो नहीं जाता है। यदि ऑपरेशन पूरा नहीं हुआ है, तो आप त्रुटि कोड की जांच कर सकते हैं और पुनः प्रयास कर सकते हैं।

2
जब आप स्क्रिप्ट लिखते हैं और निर्भरता स्थापित नहीं करना चाहते हैं, तो इसके लिए बिल्कुल सही है क्योंकि आप अपनी सभी फ़ाइलों को हटाने के बाद 30 सेकंड में इस स्क्रिप्ट को हटाने वाले हैं !!
मैथियास

हमेशा रूट फ़ाइल सिस्टम को गड़बड़ाने और हटाने के तरीके होते हैं। इस स्थिति में ओपी -fध्वज को हटा सकता है सुरक्षित होने के लिए, या यह सुनिश्चित करते हुए कि वह सब कुछ हटा नहीं रहा है। exec + rmनोड में एक वैध और उपयोगी कमांड है जिसका उपयोग मैं अक्सर परीक्षण के दौरान करता हूं।
रैश

0

काश, कुछ अतिरिक्त और सामान्य के लिए अतिरिक्त मॉड्यूल के बिना ऐसा करने का एक तरीका था, लेकिन यह सबसे अच्छा है जो मैं साथ आ सकता हूं।

अपडेट: अब विंडोज पर काम करना चाहिए (विंडोज 10 का परीक्षण किया हुआ), और लिनक्स / यूनिक्स / बीएसडी / मैक सिस्टम पर भी काम करना चाहिए।

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-extra का रास्ता है।
b01

3
यह विधि सर्वथा खतरनाक है। एक शेल कमांड का स्ट्रिंग संयोजन, विशेष रूप से भागने के बिना, कोड निष्पादन कमजोरियों और समान को आमंत्रित करता है। यदि आप rmdir का उपयोग करने जा रहे हैं, child_process.execFileतो शेल का उपयोग न करें और इसके बजाय स्पष्ट रूप से तर्क पारित करें।
नेविन

@nevyn मैं यह कोशिश करूंगा कि अगर यह काम करता है तो मेरे जवाब को अपडेट करें।
b01

हमेशा तीसरे पक्ष का उपयोग नहीं करना पसंद करते हैं! धन्यवाद!
एंटोन मिसेव

इसके अलावा, यह विधि बहुत धीमी है। Nodejs देशी एपीआई बहुत तेज है।
जर्सी

0

यह वादा को हल करने के लिए प्रॉमिस और दो हेल्प फ़ंक्शंस (टू और ऑल) का उपयोग करके एक दृष्टिकोण है।

यह सभी क्रियाओं को अतुलनीय करता है।

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

// बिना किसी तृतीय पक्ष के उपयोग के

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
यह मुझे क्या चाहिए के लिए काम करेगा, लेकिन आप स्लैश को fs.unllinkSync(path.join(FOLDER_PATH, element);
शांत

-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
मुझे लगता है कि नेस्टेड डायरेक्ट्रीज़ के लिए कुछ इस तरह काम करना चाहिए।
fool4jesus

हां, नेस्टेड डायरेक्टरी और नॉन-नेस्टेड एक के लिए दोनों
एरिसन ओलाशनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.