アプリケーションのユーザーがDCIMフォルダー(SDカードにあり、サブフォルダーを含む)を削除できるようにしたい。
もしそうなら、これは可能ですか?
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();
}
}
次のように、ファイルとフォルダーを再帰的に削除できます。
void deleteRecursive(File fileOrDirectory) {
if (fileOrDirectory.isDirectory())
for (File child : fileOrDirectory.listFiles())
deleteRecursive(child);
fileOrDirectory.delete();
}
コマンドライン引数を使用して、フォルダー全体とその内容を削除できます。
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/");
Kotlinでは、kotlin.io
パッケージのdeleteRecursively()
拡張機能を使用できます
val someDir = File("/path/to/dir")
someDir.deleteRecursively()
あなたのアプローチはファイルのみを含むフォルダにはまともですが、サブフォルダも含むシナリオを探している場合は再帰が必要です
また、戻り値の戻り値をキャプチャして、ファイルの削除が許可されていることを確認する必要があります
含める
<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();
}
以下の方法を使用して、ファイルとそのサブディレクトリを含むメインディレクトリ全体を削除します。このメソッドをもう一度呼び出した後、メインディレクトリの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();
}
たくさんの答えがありますが、少し違うので、自分で追加することにしました。 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();
再帰的に削除する必要がない場合は、次のようなものを試すことができます。
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();
}
}
}
android.os.FileUtilsをご覧ください。API21では非表示です
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;
}
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();
}
}
Javaにサブディレクトリまたはファイルがある場合、ディレクトリを削除することはできません。この2行のシンプルなソリューションを試してください。これにより、ディレクトリとディレクトリ内のコンテストが削除されます。
File dirName = new File("directory path");
FileUtils.deleteDirectory(dirName);
この行をgradleファイルに追加してプロジェクトを同期します
compile 'org.Apache.commons:commons-io:1.3.2'
これは私がすることです...(簡潔でテスト済み)
...
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
}
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");
}
}
私が知っている最も安全なコード:
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();
}
ファイルの存在を確認し、nullを処理し、ディレクトリが実際に削除されたことを確認します
ディレクトリからすべてのファイルを削除する簡単な方法:
呼び出しのみによってディレクトリからすべての画像を削除するための汎用関数です
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();
}
}
}
ドキュメント によると:
この抽象パス名がディレクトリを示さない場合、このメソッドはnullを返します。
したがって、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());
}
ここに、楽しみのためだけの非再帰的な実装を示します:
/**
* 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);
}
}
}
//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) {
}
}
ここにあなたの解決策があり、ギャラリーも更新されます。
ショートコルチンバージョン
fun File.deleteDirectory(): Boolean {
return if (exists()) {
listFiles()?.forEach {
if (it.isDirectory) {
it.deleteDirectory()
} else {
it.delete()
}
}
delete()
} else false
}
さらに別の(現代の)解決方法。
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();
}
}
}
API 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();
}
}
}
ボタンのクリックでフォルダーとその中のすべてを削除します:
my_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File folder_path = new File(Environment.getExternalStorageDirectory() + "/your_folder_name/");
if (file.exists()) {
String deleteCmd = "rm -r " + folder_path;
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec(deleteCmd);
} catch (IOException ignored) {
}
}
}
});
私はこれを入れましたが、そのペースはディレクトリ構造のあるフォルダを削除します。
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;
}
お役に立てれば。