How to delete a whole folder and content?

AndroidFile IoDirectoryDelete Directory

Android Problem Overview


I want the users of my application to be able to delete the DCIM folder (which is located on the SD card and contains subfolders).

Is this possible, if so how?

Android Solutions


Solution 1 - Android

You can delete files and folders recursively like this:

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

	fileOrDirectory.delete();
}

Solution 2 - Android

Let me tell you first thing you cannot delete the DCIM folder because it is a system folder. As you delete it manually on phone it will delete the contents of that folder, but not the DCIM folder. You can delete its contents by using the method below:

Updated as per comments

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

Solution 3 - Android

We can use the command line arguments to delete a whole folder and its contents.

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

Example usage of the above code:

deleteFiles("/sdcard/uploads/");

Solution 4 - Android

In Kotlin you can use deleteRecursively() extension from kotlin.io package

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

Solution 5 - Android

Short koltin version

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

UPDATE

Kotlin stdlib function

file.deleteRecursively()

Solution 6 - Android

use below method to delete entire main directory which contains files and it's sub directory. After calling this method once again call delete() directory of your main directory.

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

Solution 7 - Android

Your approach is decent for a folder that only contains files, but if you are looking for a scenario that also contains subfolders then recursion is needed

Also you should capture the return value of the return to make sure you are allowed to delete the file

and include

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

in your manifest

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

Solution 8 - Android

There is a lot of answers, but I decided to add my own, because it's little different. It's based on OOP ;)

I created class DirectoryCleaner, which help me each time when I need to clean some directory.

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

    }
}

It can be used to solve this problem in next way:

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

Solution 9 - Android

You can not delete the directory if it has subdirectories or files in Java. Try this two-line simple solution. This will delete the directory and contests inside the directory.

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

Add this line in gradle file and sync the project

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

Solution 10 - Android

According to the documentation:

>If this abstract pathname does not denote a directory, then this method returns null.

So you should check if listFiles is null and only continue if it's not

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

Solution 11 - Android

If you dont need to delete things recursively you can try something like this:

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

Solution 12 - Android

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

Solution 13 - Android

see android.os.FileUtils, it's hide on API 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;
}

Source: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/FileUtils.java#414

Solution 14 - Android

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

Solution 15 - Android

This is what I do... (terse and tested)

    ...
    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
    }

Solution 16 - Android

The fastest and easiest way:

public static boolean deleteFolder(File removableFolder) {
        File[] files = removableFolder.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                boolean success;
                if (file.isDirectory())
                    success = deleteFolder(file);
                else success = file.delete();
                if (!success) return false;
            }
        }
        return removableFolder.delete();
}

Solution 17 - Android

Simple way to delete all file from directory :

It is generic function for delete all images from directory by calling only

deleteAllImageFile(context);

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

Solution 18 - Android

Safest code I know:

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

Checks the file exists, handles nulls, checks the directory was actually deleted

Solution 19 - Android

//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) {
    }
}

here is your solution it will also refresh the gallery as well.

Solution 20 - Android

Here is a non-recursive implementation, just for fun:

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

Solution 21 - Android

This (Tries to delete all sub-files and sub-directories including the supplied directory):

  1. If File, delete
  2. If Empty Directory, delete
  3. if Not Empty Directory, call delete again with sub-directory, repeat 1 to 3

example:

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

To gain access to External Storage Directory, you need the following permissions:

(Use ContextCompat.checkSelfPermission and ActivityCompat.requestPermissions)

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

Recursive method:

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

Solution 22 - Android

I've put this one though its' paces it deletes a folder with any directory structure.

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;

}

Hope this helps.

Solution 23 - Android

Yet another (modern) way to solve it.

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

On Android since API 26

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

Solution 24 - Android

I'm using this recursive function to do the job:

public static void deleteDirAndContents(@NonNull File mFile){
    if (mFile.isDirectory() && mFile.listFiles() != null && mFile.listFiles().length > 0x0) {
        for (File file : mFile.listFiles()) {
            deleteDirAndContents(file);
        }
    } else {
        mFile.delete();
    }
}

The function checks if it is a directory or a file.

If it is a directory checks if it has child files, if it has child files will call herself again passing the children and repeating.

If it is a file it delete it.

(Don't use this function to clear the app cache by passing the cache dir because it will delete the cache dir too so the app will crash... If you want to clear the cache you use this function that won't delete the dir you pass to it:

public static void deleteDirContents(@NonNull File mFile){
        if (mFile.isDirectory() && mFile.listFiles() != null && mFile.listFiles().length > 0x0) {
            for (File file : mFile.listFiles()) {
                deleteDirAndContents(file);
            }
        }
    }

or you can check if it is the cache dir using:

if (!mFile.getAbsolutePath().equals(context.getCacheDir().getAbsolutePath())) {
    mFile.delete();
}

Example code to clear app cache:

public static void clearAppCache(Context context){
        try {
            File cache = context.getCacheDir();
            FilesUtils.deleteDirContents(cache);
        } catch (Exception e){
            MyLogger.onException(TAG, e);
        }
    }

Bye, Have a nice day & coding :D

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBeginnerView Question on Stackoverflow
Solution 1 - AndroidteedyayView Answer on Stackoverflow
Solution 2 - Androidchikka.anddevView Answer on Stackoverflow
Solution 3 - AndroidxinaxinoView Answer on Stackoverflow
Solution 4 - AndroidDima RostopiraView Answer on Stackoverflow
Solution 5 - AndroidVladView Answer on Stackoverflow
Solution 6 - AndroidAndroidView Answer on Stackoverflow
Solution 7 - AndroidGregMView Answer on Stackoverflow
Solution 8 - AndroidgioView Answer on Stackoverflow
Solution 9 - AndroidVigneswaran AView Answer on Stackoverflow
Solution 10 - AndroidHB.View Answer on Stackoverflow
Solution 11 - AndroidMartyView Answer on Stackoverflow
Solution 12 - AndroidDeep VermaView Answer on Stackoverflow
Solution 13 - AndroidxuxuView Answer on Stackoverflow
Solution 14 - AndroidJasonCheungView Answer on Stackoverflow
Solution 15 - AndroidSoloPilotView Answer on Stackoverflow
Solution 16 - AndroidMasterView Answer on Stackoverflow
Solution 17 - AndroidSagar ChorageView Answer on Stackoverflow
Solution 18 - AndroidGary DaviesView Answer on Stackoverflow
Solution 19 - AndroidBilal MustafaView Answer on Stackoverflow
Solution 20 - AndroidPhilLabView Answer on Stackoverflow
Solution 21 - AndroidPierreView Answer on Stackoverflow
Solution 22 - Androiduser2288580View Answer on Stackoverflow
Solution 23 - AndroidCh4rl3xView Answer on Stackoverflow
Solution 24 - AndroidZ3R0View Answer on Stackoverflow