응용 프로그램 사용자가 DCIM 폴더 (SD 카드에 있고 하위 폴더가 있음)를 삭제할 수 있기를 원합니다.
그렇다면 어떻게 가능합니까?
rm -rf directory
대신 대신 사용해야 합니다 FileUtils.deleteDirectory
. 벤치마킹 후 여러 배 더 빠르다는 것을 알았습니다. 여기에서 샘플 구현을 확인하십시오. stackoverflow.com/a/58421350/293280
응용 프로그램 사용자가 DCIM 폴더 (SD 카드에 있고 하위 폴더가 있음)를 삭제할 수 있기를 원합니다.
그렇다면 어떻게 가능합니까?
rm -rf directory
대신 대신 사용해야 합니다 FileUtils.deleteDirectory
. 벤치마킹 후 여러 배 더 빠르다는 것을 알았습니다. 여기에서 샘플 구현을 확인하십시오. stackoverflow.com/a/58421350/293280
답변:
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();
}
DCIM\foo\bar\pic.jpg
:)가 포함되도록 사용자가 자신의 SD 카드의 내용을 수정했을 가능성이 있습니다 .이 경우 chirag의 코드가 실패합니다.
fileOrDirectory.listFiles()
반환 될 수 null
있습니다. 이것은 문서에 명확하게 나와 있습니다 : developer.android.com/reference/java/io/File.html#listFiles ()
명령 줄 인수를 사용하여 전체 폴더와 내용을 삭제할 수 있습니다.
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에서는 패키지 deleteRecursively()
에서 확장을 사용할 수 있습니다kotlin.io
val someDir = File("/path/to/dir")
someDir.deleteRecursively()
FilesKt.deleteRecursively(new File("/path/to/dir"));
kotlin-stdlib를 사용 하는 경우 사용할 수 있습니다
아래 방법을 사용하여 파일과 하위 디렉토리가 포함 된 전체 기본 디렉토리를 삭제하십시오. 이 메소드를 다시 한 번 호출 한 후 기본 디렉토리의 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();
}
접근 방식은 파일 만 포함 된 폴더에 적합하지만 하위 폴더도 포함 된 시나리오를 찾는 경우 재귀가 필요합니다.
또한 반환 값을 캡처하여 파일을 삭제할 수 있는지 확인해야합니다.
포함
<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();
}
많은 답변이 있지만 조금 다르기 때문에 직접 추가하기로 결정했습니다. 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();
Java에 서브 디렉토리 나 파일이 있으면 디렉토리를 삭제할 수 없습니다. 이 두 줄 간단한 솔루션을 사용해보십시오. 디렉토리 안의 디렉토리와 컨테스트가 삭제됩니다.
File dirName = new File("directory path");
FileUtils.deleteDirectory(dirName);
gradle 파일 에이 줄을 추가하고 프로젝트를 동기화하십시오.
compile 'org.apache.commons:commons-io:1.3.2'
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();
}
}
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;
}
설명서 에 따르면 :
이 추상 패스 명이 디렉토리를 나타내지 않는 경우,이 메소드는 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());
}
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");
}
}
디렉토리에서 모든 파일을 삭제하는 간단한 방법 :
호출만으로 디렉토리에서 모든 이미지를 삭제하는 일반적인 기능입니다
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();
}
}
}
내가 아는 가장 안전한 코드 :
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();
}
파일이 있는지 확인하고 널을 처리하며 디렉토리가 실제로 삭제되었는지 확인
재미를 위해 비 재귀 구현이 있습니다.
/**
* 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);
}
}
}
이 (제공된 디렉토리를 포함하여 모든 하위 파일과 하위 디렉토리를 삭제하려고합니다) :
File
삭제Empty Directory
삭제Not Empty Directory
하위 디렉토리로 delete를 다시 호출하고 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;
}
나는 이것의 속도에 걸렸지 만 디렉토리 구조가있는 폴더를 삭제합니다.
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;
}
도움이 되었기를 바랍니다.
//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) {
}
}
여기도 해결책입니다. 갤러리도 새로 고칩니다.
그것을 해결하는 또 다른 (현대적인) 방법.
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();
}
}
}
이 재귀 함수를 사용하여 작업을 수행하고 있습니다.
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();
}
}
이 기능은 디렉토리인지 파일인지 확인합니다.
디렉토리가 하위 파일이 있는지 확인하면 하위 파일이 있으면 하위 파일을 전달하고 반복하여 자신을 다시 호출합니다.
파일이면 삭제합니다.
(캐시 디렉토리를 전달하여 앱 캐시를 지우는 데이 기능을 사용하지 마십시오. 캐시 디렉토리도 삭제되므로 앱이 충돌하기 때문에 ... 캐시를 지우려면이 기능을 사용하십시오. dir 당신은 그것에 전달합니다 :
public static void deleteDirContents(@NonNull File mFile){
if (mFile.isDirectory() && mFile.listFiles() != null && mFile.listFiles().length > 0x0) {
for (File file : mFile.listFiles()) {
deleteDirAndContents(file);
}
}
}
또는 다음을 사용하여 캐시 디렉토리인지 확인할 수 있습니다.
if (!mFile.getAbsolutePath().equals(context.getCacheDir().getAbsolutePath())) {
mFile.delete();
}
앱 캐시를 지우는 예제 코드 :
public static void clearAppCache(Context context){
try {
File cache = context.getCacheDir();
FilesUtils.deleteDirContents(cache);
} catch (Exception e){
MyLogger.onException(TAG, e);
}
}
안녕, 좋은 하루 되세요 & 코딩 : D