संपूर्ण फ़ोल्डर और सामग्री को कैसे हटाएं?


186

मैं चाहता हूं कि मेरे एप्लिकेशन के उपयोगकर्ता DCIM फ़ोल्डर (जो SD कार्ड पर स्थित है और सबफ़ोल्डर शामिल हैं) को हटाने में सक्षम हों।

क्या यह संभव है, यदि ऐसा है तो कैसे?


1
पुनरावर्ती अप-अप विलोपन दृष्टिकोण के अलावा?
सरवर इरफान

यदि आपके पास बहुत बड़ी या जटिल निर्देशिका है, तो आपको rm -rf directoryइसके बजाय उपयोग करना चाहिए FileUtils.deleteDirectory। बेंचमार्किंग के बाद हमने पाया कि यह कई गुना तेज है। एक नमूना कार्यान्वयन यहाँ देखें: stackoverflow.com/a/58421350/293280
जोशुआ पिंटर

जवाबों:


299

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

टिप्पणियों के अनुसार अपडेट किया गया

File dir = new File(Environment.getExternalStorageDirectory()+"Dir_name_here"); 
if (dir.isDirectory()) 
{
    String[] children = dir.list();
    for (int i = 0; i < children.length; i++)
    {
       new File(dir, children[i]).delete();
    }
}

3
erm मैं कैसे घोषित करूं कि dir क्या है?
शुरुआत

im मूल रूप से सभी तस्वीरों को हटाने की कोशिश कर रहा है, तो कोई बात नहीं है DCIM को तब तक नहीं हटाया जाता है जब तक कि तस्वीरें हैं ... इसलिए यहां तक ​​कि 100MEDIA फ़ोल्डर को हटाने से यह काम करना होगा
शुरुआत

1
आपको dicm फ़ोल्डर के पथ का उपयोग करके निर्देशिका घोषित करनी होगी: फ़ाइल r = फ़ाइल (पथ) का उपयोग करें;
chikka.anddev

3
उपयोग की गई फ़ाइल dir = नई फ़ाइल (Environment.getExternalStorageDirectory () + "/ DCIM / 100MEDIA");
शुरुआत

1
@chiragshah किसी फ़ोल्डर को हटाने और फ़ोल्डर को फिर से बनाने के परिणामस्वरूप एक अज्ञात फ़ाइल का निर्माण होता है जिसमें फ़ोल्डर का एक ही नाम उल्लेख किया गया है। और अगर मैं उस फ़ाइल को एक्सेस करने की कोशिश कर रहा हूं तो वह संसाधन या डिवाइस व्यस्त जैसे अपवाद फेंक रहा है। मैंने गुणों की भी जांच की। फ़ाइल जहां मैंने पाया MD5 हस्ताक्षर: ऑपरेशन में विफलता
शा

529

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

void deleteRecursive(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory())
        for (File child : fileOrDirectory.listFiles())
            deleteRecursive(child);

    fileOrDirectory.delete();
}

21
मैंने दक्षता के लिए कोई परीक्षण नहीं किया है, लेकिन मेरा मानना ​​है कि मेरा अधिक मजबूत है। चिराग की डीसीआईएम फ़ोल्डर के विशिष्ट मामले के लिए काम करेगा, जहां डीसीआईएम के भीतर फ़ोल्डर्स में केवल फाइलें होनी चाहिए (यानी डीसीआईएम के भीतर फ़ोल्डर्स आमतौर पर कोई सबफ़ोल्डर नहीं होते हैं)। मेरा संस्करण उन फ़ोल्डरों को हटा देगा जो किसी भी गहराई से नेस्टेड हैं। ऐसा मौका है कि उपयोगकर्ता ने अपने एसडी कार्ड की सामग्री को संशोधित किया है ताकि डीसीआईएम में फ़ोल्डर्स अधिक गहराई से उदा (उदा DCIM\foo\bar\pic.jpg) हो, जिस स्थिति में चिराग का कोड विफल हो जाएगा।
तेयदेय

2
एक सहकर्मी ने मुझसे एक सवाल पूछा: क्या होता है अगर एक फ़ोल्डर में खुद पर एक प्रतीकात्मक लिंक होता है और आप इस कोड के कोड को निष्पादित करते हैं?
p4u144

1
@ p4u144 अपने सहयोगी को एक प्रतिभाशाली होने के लिए एक उच्च-पाँच दें! अच्छी तरह से देखा गया! सच कहूं तो मुझे नहीं पता कि यह कोड प्रतीकात्मक लिंक का सम्मान करेगा या नहीं, लेकिन अगर ऐसा होता है तो आपके पास एक अनंत लूप होगा। क्या आप फैंसी परीक्षण कर रहे हैं?
तेयदेय 12

8
@ p4u144 प्रतीकात्मक लिंक के बारे में कोई चिंता नहीं है। "प्रतीकात्मक लिंक के साथ, लिंक हटा दिया गया है और लिंक का लक्ष्य नहीं है।" से docs.oracle.com/javase/tutorial/essential/io/delete.html
कोर्बिन

3
यहां एक संभावित एनपीई है: फाइलों को पढ़ते समय I / O त्रुटि होने पर fileOrDirectory.listFiles()वापस आ सकता है null। यह प्रलेखन में स्पष्ट रूप से कहा गया है: developer.android.com/reference/java/io/File.html#listFiles ()
ब्रायन येनचो

67

हम एक संपूर्ण फ़ोल्डर और उसकी सामग्री को हटाने के लिए कमांड लाइन के तर्कों का उपयोग कर सकते हैं।

public static void deleteFiles(String path) {

    File file = new File(path);

    if (file.exists()) {
        String deleteCmd = "rm -r " + path;
        Runtime runtime = Runtime.getRuntime();
        try {
            runtime.exec(deleteCmd);
        } catch (IOException e) { }
    }
}

उपरोक्त कोड का उदाहरण उपयोग:

deleteFiles("/sdcard/uploads/");

2
अच्छा लगता है, क्या आपको पता है कि यह सिंक्रोनस या एसिंक्रोनस है? दस्तावेज़ यह नहीं कहते हैं: developer.android.com/reference/java/lang/…
कहीं कोई

2
बुरा विचार। खोल पर क्यों करते हैं?
नोआतम


33

कोटलिन में आप पैकेज deleteRecursively()से एक्सटेंशन का उपयोग कर सकते हैंkotlin.io

val someDir = File("/path/to/dir")
someDir.deleteRecursively()

2
जावा में आप उपयोग कर सकते हैं FilesKt.deleteRecursively(new File("/path/to/dir"));यदि आप कोटलिन-स्टडलिब का उपयोग कर रहे हैं
जूनूनो

यह कमांड "/ dir" डायरेक्टरी को अंदर के कंटेंट के साथ या "/ dir" डायरेक्टरी के अंदर के कंटेंट को डिलीट कर देगा और डायरेक्टरी वहीं रह जाती है।
भीमबिंद

1
@Bhimbim lemme google डॉक्स आपके लिए "अपने सभी बच्चों के साथ यह फ़ाइल हटाएं।" तो, निर्देशिका को हटा दिया जाएगा और साथ ही सामग्री भी
दीमा रोस्तोपिरा

धन्यवाद @DimaRostopira!
भीमबिंद

बचाव के लिए kotlin!
तोबी ओइलेकान

15

संपूर्ण मुख्य निर्देशिका को हटाने के लिए विधि का उपयोग करें जिसमें फ़ाइलें हैं और यह उप निर्देशिका है। इस विधि को कॉल करने के बाद एक बार फिर अपने मुख्य निर्देशिका की डिलीट () डायरेक्टरी को कॉल करें।

// For to Delete the directory inside list of files and inner Directory
public static boolean deleteDir(File dir) {
    if (dir.isDirectory()) {
        String[] children = dir.list();
        for (int i=0; i<children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
    }

    // The directory is now empty so delete it
    return dir.delete();
}

सभी उत्तरों में से, यह केवल वास्तविक उत्तर है जो निर्देशिका को हटा देता है, इसमें फाइलें हटाने के बाद भी।
जीशान

फ़ाइल फ़ाइल = नई फ़ाइल (Environment.getExternalStorageDirectory () + विभाजक + "folder_name" + विभाजक); deleteDir (फ़ाइल); हाँ यह काम करता है। धन्यवाद :)
ashishdhiman2007

14

आपका दृष्टिकोण एक ऐसे फ़ोल्डर के लिए सभ्य है जिसमें केवल फ़ाइलें होती हैं, लेकिन यदि आप एक ऐसे परिदृश्य की तलाश कर रहे हैं जिसमें सबफ़ोल्डर्स भी हैं, तो पुनरावृत्ति की आवश्यकता है

इसके अलावा, आपको यह सुनिश्चित करने के लिए कि आपको फ़ाइल को हटाने की अनुमति है, रिटर्न का रिटर्न मान कैप्चर करना चाहिए

और शामिल हैं

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

आपके प्रकट में

void DeleteRecursive(File dir)
{
    Log.d("DeleteRecursive", "DELETEPREVIOUS TOP" + dir.getPath());
    if (dir.isDirectory())
    {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++)
        {
            File temp = new File(dir, children[i]);
            if (temp.isDirectory())
            {
                Log.d("DeleteRecursive", "Recursive Call" + temp.getPath());
                DeleteRecursive(temp);
            }
            else
            {
                Log.d("DeleteRecursive", "Delete File" + temp.getPath());
                boolean b = temp.delete();
                if (b == false)
                {
                    Log.d("DeleteRecursive", "DELETE FAIL");
                }
            }
        }

    }
    dir.delete();
}

5
यदि आप के लिए उपयोग आसान हो सकता है (फ़ाइल currentFile: file.listFiles ()) {
Thorben

8

बहुत सारे उत्तर हैं, लेकिन मैंने खुद को जोड़ने का फैसला किया, क्योंकि यह थोड़ा अलग है। यह OOP पर आधारित है;)

मैंने क्लास डाइरेक्टरी क्लीनेर बनाया , जो हर बार मेरी मदद करता है जब मुझे कुछ डायरेक्टरी को साफ करने की आवश्यकता होती है।

public class DirectoryCleaner {
    private final File mFile;

    public DirectoryCleaner(File file) {
        mFile = file;
    }

    public void clean() {
        if (null == mFile || !mFile.exists() || !mFile.isDirectory()) return;
        for (File file : mFile.listFiles()) {
            delete(file);
        }
    }

    private void delete(File file) {
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                delete(child);
            }
        }
        file.delete();

    }
}

इसका उपयोग इस समस्या को अगले तरीके से हल करने के लिए किया जा सकता है:

File dir = new File(Environment.getExternalStorageDirectory(), "your_directory_name");
new DirectoryCleaner(dir).clean();
dir.delete();

7

यदि आपको पुनरावर्ती चीजों को हटाने की आवश्यकता नहीं है, तो आप कुछ इस तरह की कोशिश कर सकते हैं:

File file = new File(context.getExternalFilesDir(null), "");
    if (file != null && file.isDirectory()) {
        File[] files = file.listFiles();
        if(files != null) {
            for(File f : files) {   
                f.delete();
            }
        }
    }

6

यदि जावा में उपनिर्देशिका या फाइलें हैं तो आप निर्देशिका को हटा नहीं सकते। इस दो-लाइन सरल समाधान का प्रयास करें। यह निर्देशिका को हटा देगा और निर्देशिका के अंदर प्रतियोगिता होगी।

File dirName = new File("directory path");
FileUtils.deleteDirectory(dirName);

इस लाइन को gradle फ़ाइल में जोड़ें और प्रोजेक्ट सिंक करें

compile 'org.apache.commons:commons-io:1.3.2'  

2 लाइनर के रूप में, यह सरल है। लेकिन सिर्फ एक तरीके का उपयोग करने के लिए पूरी लाइब्रेरी स्थापित करना अक्षम लगता है। इसके बजाय इसका उपयोग करें
काथिर

ग्रेड सम्मिलित करें टिप ने मेरी जान बचाई।
Dracarys

5
public static void deleteDirectory( File dir )
{

    if ( dir.isDirectory() )
    {
        String [] children = dir.list();
        for ( int i = 0 ; i < children.length ; i ++ )
        {
         File child =    new File( dir , children[i] );
         if(child.isDirectory()){
             deleteDirectory( child );
             child.delete();
         }else{
             child.delete();

         }
        }
        dir.delete();
    }
}

5

android.os.FileUtils देखें, तो यह एपीआई 21 पर छिपा है

public static boolean deleteContents(File dir) {
    File[] files = dir.listFiles();
    boolean success = true;
    if (files != null) {
        for (File file : files) {
            if (file.isDirectory()) {
                success &= deleteContents(file);
            }
            if (!file.delete()) {
                Log.w("Failed to delete " + file);
                success = false;
            }
        }
    }
    return success;
}

स्रोत: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/FileUtils.java#414


4

प्रलेखन के अनुसार :

यदि यह सार पथ नाम निर्देशिका को निरूपित नहीं करता है, तो यह विधि शून्य हो जाती है।

तो आपको यह देखना चाहिए कि क्या listFilesहै nullऔर अगर जारी नहीं है तो ही जारी रखें

boolean deleteDirectory(File path) {
    if(path.exists()) {
        File[] files = path.listFiles();
        if (files == null) {
            return false;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                deleteDirectory(file);
            } else {
                boolean wasSuccessful = file.delete();
                if (wasSuccessful) {
                    Log.i("Deleted ", "successfully");
                }
            }
        }
    }
    return(path.delete());
}

1
यह स्वीकृत उत्तर होना चाहिए। एक जादू की तरह काम करता है!
MSeiz5

3

यह वही है जो मैं करता हूँ ... (कविता और परीक्षण)

    ...
    deleteDir(new File(dir_to_be_deleted));
    ...

    // delete directory and contents
    void deleteDir(File file) { 
        if (file.isDirectory())
            for (String child : file.list())
                deleteDir(new File(file, child));
        file.delete();  // delete child file or empty directory
    }

3
private static void deleteRecursive(File dir)
{
    //Log.d("DeleteRecursive", "DELETEPREVIOUS TOP" + dir.getPath());
    if (dir.isDirectory())
    {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++)
        {
            File temp = new File(dir, children[i]);
            deleteRecursive(temp);
        }

    }

    if (dir.delete() == false)
    {
        Log.d("DeleteRecursive", "DELETE FAIL");
    }
}

2

निर्देशिका से सभी फ़ाइल को हटाने का सरल तरीका:

यह केवल कॉल करके निर्देशिका से सभी छवियों को हटाने के लिए सामान्य कार्य है

deleteAllImageFile (संदर्भ);

public static void deleteAllFile(Context context) {
File directory = context.getExternalFilesDir(null);
        if (directory.isDirectory()) {
            for (String fileName: file.list()) {
                new File(file,fileName).delete();
            }
        }    
    } 

2

सबसे सुरक्षित कोड मुझे पता है:

private boolean recursiveRemove(File file) {
    if(file == null  || !file.exists()) {
        return false;
    }

    if(file.isDirectory()) {
        File[] list = file.listFiles();

        if(list != null) {

            for(File item : list) {
                recursiveRemove(item);
            }

        }
    }

    if(file.exists()) {
        file.delete();
    }

    return !file.exists();
}

फ़ाइल मौजूद है चेक करता है, नल संभालता है, जाँचता है कि निर्देशिका वास्तव में हटा दी गई थी


2

लघु कोल्टिन संस्करण

fun File.deleteDirectory(): Boolean {
    return if (exists()) {
        listFiles()?.forEach {
            if (it.isDirectory) {
                it.deleteDirectory()
            } else {
                it.delete()
            }
        }
        delete()
    } else false
}

1

यहाँ एक गैर-पुनरावर्ती कार्यान्वयन है, सिर्फ मनोरंजन के लिए:

/**
 * Deletes the given folder and all its files / subfolders.
 * Is not implemented in a recursive way. The "Recursively" in the name stems from the filesystem command
 * @param root The folder to delete recursively
 */
public static void deleteRecursively(final File root) {
    LinkedList<File> deletionQueue = new LinkedList<>();
    deletionQueue.add(root);

    while(!deletionQueue.isEmpty()) {
        final File toDelete = deletionQueue.removeFirst();
        final File[] children = toDelete.listFiles();
        if(children == null || children.length == 0) {
            // This is either a file or an empty directory -> deletion possible
            toDelete.delete();
        } else {
            // Add the children before the folder because they have to be deleted first
            deletionQueue.addAll(Arrays.asList(children));
            // Add the folder again because we can't delete it yet.
            deletionQueue.addLast(toDelete);
        }
    }
}

1

यह (आपूर्ति निर्देशिका सहित सभी उप-फ़ाइलों और उप-निर्देशिकाओं को हटाने की कोशिश करता है) :

  1. यदि File, हटाएं
  2. यदि Empty Directory, हटाएं
  3. यदि Not Empty Directory, उप-निर्देशिका के साथ फिर से कॉल हटाएं, तो 1 से 3 दोहराएं

उदाहरण:

File externalDir = Environment.getExternalStorageDirectory()
Utils.deleteAll(externalDir); //BE CAREFUL.. Will try and delete ALL external storage files and directories

बाहरी संग्रहण निर्देशिका तक पहुंच प्राप्त करने के लिए, आपको निम्नलिखित अनुमतियों की आवश्यकता है:

(प्रयोग ContextCompat.checkSelfPermissionऔर ActivityCompat.requestPermissions)

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

पुनरावर्ती विधि:

public static boolean deleteAll(File file) {
    if (file == null || !file.exists()) return false;

    boolean success = true;
    if (file.isDirectory()) {
        File[] files = file.listFiles();
        if (files != null && files.length > 0) {
            for (File f : files) {
                if (f.isDirectory()) {
                    success &= deleteAll(f);
                }
                if (!f.delete()) {
                    Log.w("deleteAll", "Failed to delete " + f);
                    success = false;
                }
            }
        } else {
            if (!file.delete()) {
                Log.w("deleteAll", "Failed to delete " + file);
                success = false;
            }
        }
    } else {
        if (!file.delete()) {
            Log.w("deleteAll", "Failed to delete " + file);
            success = false;
        }
    }
    return success;
}

0

मैंने इसे एक डाल दिया है, हालांकि इसके 'पेस' इसे किसी भी निर्देशिका संरचना के साथ एक फ़ोल्डर को हटा देते हैं।

public int removeDirectory(final File folder) {

    if(folder.isDirectory() == true) {
        File[] folderContents = folder.listFiles();
        int deletedFiles = 0;

        if(folderContents.length == 0) {
            if(folder.delete()) {
                deletedFiles++;
                return deletedFiles;
            }
        }
        else if(folderContents.length > 0) {

            do {

                File lastFolder = folder;
                File[] lastFolderContents = lastFolder.listFiles();

                //This while loop finds the deepest path that does not contain any other folders
                do {

                    for(File file : lastFolderContents) {

                        if(file.isDirectory()) {
                            lastFolder = file;
                            lastFolderContents = file.listFiles();
                            break;
                        }
                        else {

                            if(file.delete()) {
                                deletedFiles++;
                            }
                            else {
                                break;
                            }

                        }//End if(file.isDirectory())

                    }//End for(File file : folderContents)

                } while(lastFolder.delete() == false);

                deletedFiles++;
                if(folder.exists() == false) {return deletedFiles;}

            } while(folder.exists());
        }
    }
    else {
        return -1;
    }

    return 0;

}

उम्मीद है की यह मदद करेगा।


0
//To delete all the files of a specific folder & subfolder
public static void deleteFiles(File directory, Context c) {
    try {
        for (File file : directory.listFiles()) {
            if (file.isFile()) {
                final ContentResolver contentResolver = c.getContentResolver();
                String canonicalPath;
                try {
                    canonicalPath = file.getCanonicalPath();
                } catch (IOException e) {
                    canonicalPath = file.getAbsolutePath();
                }
                final Uri uri = MediaStore.Files.getContentUri("external");
                final int result = contentResolver.delete(uri,
                        MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
                if (result == 0) {
                    final String absolutePath = file.getAbsolutePath();
                    if (!absolutePath.equals(canonicalPath)) {
                        contentResolver.delete(uri,
                                MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
                    }
                }
                if (file.exists()) {
                    file.delete();
                    if (file.exists()) {
                        try {
                            file.getCanonicalFile().delete();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        if (file.exists()) {
                            c.deleteFile(file.getName());
                        }
                    }
                }
            } else
                deleteFiles(file, c);
        }
    } catch (Exception e) {
    }
}

यहां आपका समाधान है कि यह गैलरी को भी ताज़ा करेगा।


0

फिर भी इसे हल करने का एक और (आधुनिक) तरीका।

public class FileUtils {
    public static void delete(File fileOrDirectory) {
        if(fileOrDirectory != null && fileOrDirectory.exists()) {
            if(fileOrDirectory.isDirectory() && fileOrDirectory.listFiles() != null) {      
                Arrays.stream(fileOrDirectory.listFiles())
                      .forEach(FileUtils::delete);
            }
            fileOrDirectory.delete();
        }
    }
}

एपीआई 26 के बाद से Android पर

public class FileUtils {

    public static void delete(File fileOrDirectory)  {
        if(fileOrDirectory != null) {
            delete(fileOrDirectory.toPath());
        }
    }

    public static void delete(Path path)  {
        try {
            if(Files.exists(path)) {
                Files.walk(path)
                        .sorted(Comparator.reverseOrder())
                        .map(Path::toFile)
//                      .peek(System.out::println)
                        .forEach(File::delete);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.