निर्देशिका में सभी फ़ाइलें हटाएं (लेकिन निर्देशिका नहीं) - एक लाइनर समाधान


201

मैं एबीसी निर्देशिका के अंदर सभी फ़ाइलों को हटाना चाहता हूं।

जब मैंने FileUtils.deleteDirectory(new File("C:/test/ABC/"));इसके साथ प्रयास किया तो फ़ोल्डर ABC को भी हटा दिया।

क्या एक लाइनर समाधान है जहां मैं निर्देशिका के अंदर फ़ाइलों को हटा सकता हूं लेकिन निर्देशिका नहीं?


2
Thats क्योंकि .deleteDirectory (यहां तक ​​कि नाम इसका अर्थ है) का उपयोग निर्देशिका को हटाने के लिए किया जाता है। अगर यह फाइल डायरेक्टरी नहीं है तो उसे वह निर्देशिका मिलेगी।
user1534664

FileUtils वर्ग के अंदर अन्य कार्यों की तलाश करने की कोशिश करें, जो निर्देशिका के बजाय फ़ाइलों को हटा दें।
user1534664


1
आपको विशेष रूप से वन-लाइनर की आवश्यकता क्यों है? प्रदर्शन मानदंड नहीं हो सकता है, क्योंकि कोई भी 3 पार्टी लाइब्रेरी विधि, केवल पुनरावृत्ति ही करेगी। तो यह आपको वही प्रदर्शन देगा?
रोहित जैन 13

1
एक चीज जो आप कर सकते हैं वह है निर्देशिका को हटाना और फिर उसे फिर से बनाना। हमने पाया कि उपयोग करने rm -rf directory; mkdir directoryकी तुलना में उपयोग तेज था FileUtils.cleanDirectory
जोशुआ पिंटर

जवाबों:


362
import org.apache.commons.io.FileUtils;

FileUtils.cleanDirectory(directory); 

एक ही फ़ाइल में यह विधि उपलब्ध है। यह उनके तहत सभी उप-फ़ोल्डर और फ़ाइलों को भी पुन: हटा देगा।

डॉक्स: org.apache.commons.io.FileUtils.cleanDirectory


49
अच्छा लगा, लोगों को इसे देखने से रोकने के लिए भी; यहाँ आयात है: import org.apache.commons.io.FileUtils;
पॉल ग्रीगोइरे

5
मुझे अभी भी यह देखना है कि आयात क्यों नहीं पाया जा सकता है। ऐसा इसलिए है क्योंकि किसी को इसे apache.org से डाउनलोड करना होगा ।
टॉम ज़ातो -

सुंदर समाधान। ग्रेड द्वारा इस परिवाद की जाँच करें: "कॉमन्स-आईओ: कॉमन्स-आईओ: +"
लियो गुयेन

1
ग्रेड निर्भरता - संकलन समूह: 'कॉमन्स-आईओ', नाम: 'कॉमन्स-आईओ', संस्करण: '2.5'।
जयदेव

ध्यान दें, हमने पाया rm -rf directoryकि उपयोग करने की तुलना में कॉलिंग अधिक कुशल थी FileUtils.cleanDirectory
जोशुआ पिंटर

267

क्या आपका मतलब है?

for(File file: dir.listFiles()) 
    if (!file.isDirectory()) 
        file.delete();

यह केवल फाइलों को हटा देगा, निर्देशिकाओं को नहीं।


65
यह बेहतर उत्तर निश्चित है, क्योंकि यह बाहरी परिवाद का उपयोग नहीं करता है!
एलेक्सविन

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

10
यदि आप रूट "dir" निर्देशिका के अंदर उपनिर्देशिकाएँ हैं, तो सब कुछ हटाने में विफल रहेंगे।
टियागो

2
@TiagoT सच है, यह उप-निर्देशिका को नहीं हटाएगा जो खाली नहीं हैं।
पीटर लॉरी

4
for(File file: dir.listFiles())शायद के रूप में .... मतलब है for (File file : new java.io.File("C:\\DeleteMeFolder").listFiles())...
हर्टमट पी

62

पीटर लॉरी का जवाब बहुत अच्छा है क्योंकि यह सरल है और कुछ विशेष पर निर्भर नहीं करता है, और यह तरीका है कि आपको इसे करना चाहिए। यदि आपको ऐसी कुछ चीज़ों की आवश्यकता है जो उपनिर्देशिका और उनकी सामग्री को हटा दें, तो पुनरावर्तन का उपयोग करें:

void purgeDirectory(File dir) {
    for (File file: dir.listFiles()) {
        if (file.isDirectory())
            purgeDirectory(file);
        file.delete();
    }
}

उपनिर्देशिका और उनकी सामग्री (आपके प्रश्न का हिस्सा) को छोड़ने के लिए, इस प्रकार संशोधित करें:

void purgeDirectoryButKeepSubDirectories(File dir) {
    for (File file: dir.listFiles()) {
        if (!file.isDirectory())
            file.delete();
    }
}

या, चूंकि आप एक-पंक्ति समाधान चाहते थे:

for (File file: dir.listFiles())
    if (!file.isDirectory())
        file.delete();

इस तरह के तुच्छ कार्य के लिए बाहरी पुस्तकालय का उपयोग करना एक अच्छा विचार नहीं है जब तक कि आपको इस पुस्तकालय के लिए किसी और चीज की आवश्यकता न हो, इस मामले में मौजूदा कोड का उपयोग करना बेहतर होगा। आप वैसे भी अपाचे पुस्तकालय का उपयोग करते हुए दिखाई देते हैं इसलिए इसकी FileUtils.cleanDirectory()विधि का उपयोग करें ।


1
दूसरी ओर, यदि कोई बाहरी पुस्तकालय का उपयोग करने वाला पहला व्यक्ति नहीं है, तो इसकी संभावना कम है कि अन्य लोग उस बाहरी पुस्तकालय में समान व्यवहार खोजने की उम्मीद करेंगे, और कम संभावना है कि वे वहां देखेंगे ... हमारे पास पर्याप्त नहीं है यहाँ नहीं आविष्कार किया? यदि पुस्तकालय मेरे प्रोजेक्ट में जोड़ने के लिए सामंजस्यपूर्ण और आसान है, तो मैं लगभग हमेशा पुस्तकालय जोड़ना पसंद करता हूं।
जेबी रेन्सबर्गर

33

जावा 8 स्ट्रीम

यह केवल एबीसी से फाइलें हटाता है (उप-निर्देशिका अछूता है):

Arrays.stream(new File("C:/test/ABC/").listFiles()).forEach(File::delete);

यह ABC (और उप-निर्देशिका) से केवल फ़ाइलें हटाता है :

Files.walk(Paths.get("C:/test/ABC/"))
                .filter(Files::isRegularFile)
                .map(Path::toFile)
                .forEach(File::delete);

^ इस संस्करण को IOException को संभालने की आवश्यकता है


1
दूसरा उप-निर्देशिका (परीक्षण किया गया) को नहीं हटाता है
edwise

1
@ जारी करें हां, यह एबीसी से सभी फाइलों और उप-निर्देशिकाओं से सभी फाइलों को हटा देता है। अंग्रेजी थोड़ी अस्पष्ट है।
नॉनलाइनयरफ्रूट

11

या जावा 8 में इसका उपयोग करने के लिए:

try {
  Files.newDirectoryStream( directory ).forEach( file -> {
    try { Files.delete( file ); }
    catch ( IOException e ) { throw new UncheckedIOException(e); }
  } );
}
catch ( IOException e ) {
  e.printStackTrace();
}

यह एक बहुत ही भारी है, अन्यथा यह एक लाइनर होगा अपवाद है, दया है ...


तुम्हें कैसे पता है कि फाइल करते है वास्तव में और नहीं किसी निर्देशिका के लिए फ़ाइल?
Stephan

1
यह निर्देशिका को हटा भी देता है, इसलिए यह विषय से समस्या का हल नहीं है
मार्क्स

5
public class DeleteFile {
    public static void main(String[] args) {
        String path="D:\test"; 
        File file = new File(path);
        File[] files = file.listFiles(); 
        for (File f:files) 
        {if (f.isFile() && f.exists) 
            { f.delete();
system.out.println("successfully deleted");
            }else{
system.out.println("cant delete a file due to open or error");
} }  }}

2

एक अन्य जावा 8 स्ट्रीम समाधान एक फ़ोल्डर की सभी सामग्री को हटाने के लिए, उप निर्देशिकाओं में शामिल है, लेकिन स्वयं फ़ोल्डर नहीं।

उपयोग:

Path folder = Paths.get("/tmp/folder");
CleanFolder.clean(folder);

और कोड:

public interface CleanFolder {
    static void clean(Path folder) throws IOException {

        Function<Path, Stream<Path>> walk = p -> {
            try { return Files.walk(p);
        } catch (IOException e) {
            return Stream.empty();
        }};

        Consumer<Path> delete = p -> {
            try {
                Files.delete(p);
            } catch (IOException e) {
            }
        };

        Files.list(folder)
            .flatMap(walk)
            .sorted(Comparator.reverseOrder())
            .forEach(delete);
    }
}

Files.walk या Files.delete को शामिल करने वाले हर स्ट्रीम समाधान के साथ समस्या यह है कि ये विधियाँ IOException को फेंकती हैं जो धाराओं को संभालने के लिए एक दर्द है।

मैंने एक ऐसा समाधान बनाने की कोशिश की, जो अधिक से अधिक संक्षिप्त हो।


इसके बजाय वॉक फंक्शन में एक अशक्त लौटने के लिए एक खाली स्ट्रीम (Stream.empty ()) वापस करना बेहतर होगा। यह क्लीनर है और फ़ंक्शन हमेशा एक धारा देता है। जब संभव हो तो अशांति से बचना चाहिए।
काबा k१३

धन्यवाद, मैंने आपके सुझाव के साथ उत्तर में सुधार किया
हाईजैक

2

निर्देशिका से सभी फ़ाइलों को हटाने के लिए "C: \ Example" कहें

File file = new File("C:\\Example");      
String[] myFiles;    
if (file.isDirectory()) {
    myFiles = file.list();
    for (int i = 0; i < myFiles.length; i++) {
        File myFile = new File(file, myFiles[i]); 
        myFile.delete();
    }
}

2

rm -rfकी तुलना में अधिक प्रदर्शन था FileUtils.cleanDirectory

एक-लाइनर समाधान नहीं है, लेकिन व्यापक बेंचमार्किंग के बाद, हमने पाया कि उपयोग करने rm -rfकी तुलना में कई गुना अधिक तेज था FileUtils.cleanDirectory

बेशक, यदि आपके पास एक छोटी या सरल निर्देशिका है, तो इससे कोई फर्क नहीं पड़ेगा, लेकिन हमारे मामले में हमारे पास कई गीगाबाइट्स और गहरी नेस्टेड उप निर्देशिकाएं थीं, जहां 10 मिनट से अधिक FileUtils.cleanDirectoryऔर केवल 1 मिनट का समय लगेगा rm -rf

यहाँ ऐसा करने के लिए हमारे मोटे तौर पर जावा कार्यान्वयन है:

// Delete directory given and all subdirectories and files (i.e. recursively).
//
static public boolean clearDirectory( File file ) throws IOException, InterruptedException {

    if ( file.exists() ) {

        String deleteCommand = "rm -rf " + file.getAbsolutePath();
        Runtime runtime = Runtime.getRuntime();

        Process process = runtime.exec( deleteCommand );
        process.waitFor();

        file.mkdirs(); // Since we only want to clear the directory and not delete it, we need to re-create the directory.

        return true;
    }

    return false;

}

यदि आप बड़े या जटिल निर्देशिकाओं के साथ काम कर रहे हैं तो बेहतर प्रयास करें।


1
package com;
import java.io.File;
public class Delete {
    public static void main(String[] args) {

        String files; 
        File file = new File("D:\\del\\yc\\gh");
        File[] listOfFiles = file.listFiles(); 
        for (int i = 0; i < listOfFiles.length; i++) 
        {
            if (listOfFiles[i].isFile()) 
            {
                files = listOfFiles[i].getName();
                System.out.println(files);
                if(!files.equalsIgnoreCase("Scan.pdf"))
                {
                    boolean issuccess=new File(listOfFiles[i].toString()).delete();
                    System.err.println("Deletion Success "+issuccess);
                }
            }
        }
    }
}

यदि आप सभी फ़ाइलों को हटाना चाहते हैं

if(!files.equalsIgnoreCase("Scan.pdf"))

बयान यह काम करेगा।


0

मुझे लगता है कि यह काम करेगा (NonlinearFruit पिछले जवाब के आधार पर):

Files.walk(Paths.get("C:/test/ABC/"))
                .sorted(Comparator.reverseOrder())
                .map(Path::toFile)
                .filter(item -> !item.getPath().equals("C:/test/ABC/"))
                .forEach(File::delete);

चीयर्स!

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