2011-02-09 3 views
133

Я хочу, чтобы пользователи моего приложения могли удалять папку DCIM (которая находится на SD-карте и содержит подпапки).Как удалить всю папку и содержимое?

Возможно ли это, если да, то каким образом?

+1

кроме рекурсивной снизу вверх делеции подхода? –

ответ

234

Позвольте мне сказать вам, что вы не можете удалить папку DCIM, потому что это системная папка. Когда вы удаляете его вручную по телефону, он удаляет содержимое этой папки, но не папку 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? – Beginner

+0

im в основном пытается удалить все фотографии, поэтому не имеет значения, DCIM не удаляется до тех пор, пока фотографии ... так что даже удаляя 100MEDIA, папка внутри этого будет выполнять задание – Beginner

+1

, вам нужно объявить каталог, используя путь к папке dicm : использовать файл r = файл (путь); –

12

Ваш подход является достойной для папки, которая содержит только файлы, но если вы ищете сценарий, который также содержит вложенные папки, то рекурсии требуется

Кроме того, вы должны захватить возвращаемое значение возвращения, чтобы убедиться, что вы имеете право удалить файл

и включает

<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

Это может быть проще, если вы используете для (File currentFile: file.listFiles()) { – Thorben

54

Мы можем использовать командную строку, чтобы удалить всю папку и ее содержимое.

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

Пример Useage,

deleteFiles("/sdcard/uploads/"); 
+2

кажется хорошим, знаете ли вы, является ли это синхронным или асинхронным? Документация не указала: http://developer.android.com/reference/java/lang/Runtime.html#exec%28java.lang.String[],%20java.lang.String[]%29 –

+2

Это намного быстрее, чем от Java-кода? –

+1

так просто (y) –

5

Если вам не нужно удалять вещи рекурсивно, вы можете попробовать что-то вроде этого:

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

Вы можете удалить файлы и папки рекурсивно, как это:

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

    fileOrDirectory.delete(); 
} 
+0

teedyay, можете ли вы сказать, что ваш ответ эффективен, чем чираг. На самом деле я думаю, что ответ Чирага эффективен, но люди больше уделяли вам внимание. Я новичок в java, так что вы можете указать, какой из них мне использовать. Честный ответ был бы оценен. –

+18

Я не проводил тестов на эффективность, но я считаю, что мой более надежный. chirag будет работать для конкретного случая папки DCIM, где папки в DCIM должны содержать только файлы (т. е. папки в DCIM обычно не содержат подпапок). Моя версия удалит папки, вложенные в любую глубину. Есть вероятность, что пользователь изменил содержимое своей SD-карты, так что DCIM содержит более глубоко вложенные папки (например, 'DCIM \ foo \ bar \ pic.jpg'), и в этом случае код хирага не удастся. – teedyay

+2

Вопрос, заданный коллегой: Что произойдет, если папка имеет символическую ссылку на себя, и вы выполняете этот кусок кода? – p4u144

4
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(); 
    } 
} 
2
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"); 
    } 
} 
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 
    } 
9

использование ниже способа удалить весь основной каталог, который содержит файлы, и это суб-каталог. После вызова этого метода еще раз вызовите каталог delete() вашего основного каталога.

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

Из всех ответов это единственный реальный ответ, который удаляет каталог слишком после удаление файлов в нем. – zeeshan

+0

Файл файла = новый файл (Environment.getExternalStorageDirectory() + разделитель + "имя_папки" + разделитель); deleteDir (файл); Да, это работает. Благодаря :) – ashishdhiman2007

4

Существует много ответов, но я решил добавить свои собственные, потому что это немного другое. Он основан на OOP;)

Я создал класс DirectoryCleaner, который помогает мне каждый раз, когда мне нужно очистить какой-то каталог.

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

см android.os.FileUtils, это скрыть от 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; 
} 

Источник: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/FileUtils.java#414

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

Safest код Я знаю:

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

Проверяет файл существует, обрабатывает аннулирует, проверяет каталог был фактически удален

0

Вы не можете удалить каталог, если он имеет подкаталоги или файлы. Попробуйте это двухстрочное простое решение. Это приведет к удалению каталога и конкурсов внутри каталога.

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

Добавьте эту строку в файл Gradle и синхронизировать проекту

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

В Котлин вы можете использовать deleteRecursively() расширение из kotlin.io пакета

val someDir = File("/path/to/dir") 
someDir.deleteRecursively() 
Смежные вопросы