Java를 사용하여 파일이있는 폴더를 삭제하는 방법


104

Java를 사용하여 디렉토리를 만들고 삭제하고 싶지만 작동하지 않습니다.

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}

3
시도했을 때 무슨 일이 있었습니까?
Abimaran Kugathasan 2013

질문은 무엇입니까?
Aniket Thakur 2013

1
인덱스 파일은 제거되지 않습니다.
Mr.G 2013


1
불행히도 @AniketThakur, 그 접근 방식은 심볼릭 링크를 따르고 의도하지 않은 파일과 디렉토리를 삭제합니다.
Hank Schultz

답변:


99

Java는 데이터가있는 폴더를 삭제할 수 없습니다. 폴더를 삭제하기 전에 모든 파일을 삭제해야합니다.

다음과 같이 사용하십시오.

String[]entries = index.list();
for(String s: entries){
    File currentFile = new File(index.getPath(),s);
    currentFile.delete();
}

그런 다음 index.delete() Untested 를 사용하여 폴더를 삭제할 수 있어야합니다 !


37
비어 있지 않은 하위 디렉터리는 삭제되지 않습니다.
Francesco Menzani

13
재귀 메서드를 작성하거나 FileUtils.deleteDirectory@Francesco Menzani가 말한대로 사용해야합니다.
EN20

4
정말 조심하세요. 색인이 다른 디렉토리에 대한 심볼릭 링크 인 경우 다른 디렉토리의 내용을 삭제하게됩니다. 불행히도 Java 7은 Files.isSymbolicLink ()를 제공하지만 Windows에서 Java 6의 기호 링크를 감지하는 좋은 방법을 아직 찾지 못했습니다.
Hank Schultz 2015

1
솔루션 :이 코드 덩어리를 if (!index.delete()) {...}. 그런 다음 인덱스가 심볼릭 링크 인 경우 내용이 있는지 여부에 관계없이 삭제됩니다.
Hank Schultz 2015

디렉토리를 읽는 동안 I / O 예외가있는 경우 NullPointerException이 발생합니다. 코드 entries는 null 인지 확인해야합니다 .
mernst

178

한 줄로.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

여기에 문서화



13
음 .. 아니야. 이것은 기억해야 할 중요한 사항 인 외부 종속성이있는 한 줄짜리입니다. 이와 같은 외부 종속성을 사용하는 유일한 경우는 개인 주택 프로젝트를 수행하거나 회사가 소송을 당할 가능성에 대해 신경 쓰지 않는 경우입니다.
searchengine27

11
@ searchengine27 그러나 라이브러리가 Apache Commons 아래에 있으므로 고소 될 위험은 무시할 수있는 수준 입니다 . whitesourcesoftware.com/whitesource-blog/…
simtim

1
@simtim 당신은 요점을 완전히 놓치고 있습니다. 회사는 변호사 팀이 사용 약관 및 최종 사용자 계약 및 라이브러리와 관련된 기타 법적 문서를 먼저 넘기지 않고는 라이브러리 사용을 승인하지 않습니다. 누군가는 그 변호사들에게 돈을 지불해야합니다 ... 때로는 아무도 원하지 않는데, 이는 개발자가 그것을 사용할 수 없다는 것을 의미합니다. 당신이 일하는 회사가 클수록 더 많은 빨간 테이프를 거쳐야합니다.
searchengine27

19
@ searchengine27 아니요, 요점을 완전히 놓치고 있습니다. 아파치 커먼즈 사용을 허용하기 위해 변호사 군대가 필요한 회사는 절대적인 병리이며 IT 세계의 표준에 가까운 것은 없습니다. 나는 그런 문제를 가진 사람에 대해 들어 본 적이 없으며 그러한 문제가 있으면 SO에 대한 액세스가 차단되어 어쨌든 대답에 액세스 할 수 없습니다.
9ilsdx 9rvj 0lo

94

이것은 작동하며 디렉터리 테스트를 건너 뛰는 것은 비효율적으로 보이지만 그렇지 않습니다. 테스트는 listFiles().

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            deleteDir(f);
        }
    }
    file.delete();
}

다음 기호 링크를 방지하려면 업데이트하십시오.

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}

2
결과적으로 이것에 버그가 있습니다. 루프 중에 다른 프로세스가 파일을 삭제하면 예외가 발생하여 무시해야 할 수 있습니다.
Jeff Learman

2
@ 9ilsdx9rvj0lo 엉뚱한 대신 심 링크를 처리하는 편집을 제공 할 수 있습니다. OP는 그의 게시물에서 심볼릭 링크에 대해 언급 하지 않았습니다 . 디렉토리를 만들고 삭제하기 만하면됩니다. 또한 "누락 된 많은 것"을 나열하십시오. 우리를 도와주세요.
Perry Tew

@PerryTew 나는 snarky하지 않습니다. 나는 외부 라이브러리가 사용되지 않기 때문에 대답이 더 낫다는 귀하의 의견에 완전히 동의하지 않는다는 것을 지적하고 있습니다. 그렇지 않습니다. 사람들이 아파치 커먼즈를 사용하는 타당한 이유가 있습니다. 여러분이 직접 프로그래밍 할 필요가 없습니다. Symlink는 처음부터 모든 것을 작성하는 것을 놓칠 수있는 예일뿐입니다.
9ilsdx 9rvj 0lo

2
더 나은 / 나쁜 문제가 아니라 장단점입니다. 외부 라이브러리에 의존하지 않는 것은 때때로 중요한 이점입니다. 물론 검증 된 소프트웨어를 사용하면 상당한 이점이 있습니다. 문제의 균형을 맞추는 것은 개발자의 몫입니다. 이미 언급 한 두 가지가 아닌 다른 버그가 있다면 그에 대해 알고 싶습니다.
Jeff Learman

31

Java 8에서이 솔루션을 선호합니다.

  Files.walk(pathToBeDeleted)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .forEach(File::delete);

이 사이트에서 : http://www.baeldung.com/java-delete-directory


2
전체 목록을 작성하고 정렬 된 복사본을 만든 다음 정렬 된 복사본을 반복하므로 확장 성 문제가있을 수 있습니다. 기억력이 무궁무진하지 않았던 끔찍한 옛날에는 이것은 매우 나쁜 생각이었습니다. 간결하지만 공간 비용 (O (N) 대 O (1))과 효율성 (O (N log N) 대 O (N))이 있습니다. 이것은 대부분의 사용 사례에서 중요하지 않습니다.
Jeff Learman 2018

나는 "공간 O (N) O (깊이) 대"위의 깊이 디렉토리 트리의 깊이입니다 말했다한다 (재귀 사람이 솔루션을 비교.)
제프 Learman

1
이것은 우아하고 작동하며 외부 라이브러리에 의존하지 않습니다.
Leo

파일 핸들 누수 문제가 없나요? 이 예제는 API 문서에 명시 적으로 표시된에서 반환 된 스트림을 닫지 않습니다Files.walk() . Files.list()예를 들어에서 반환 된 스트림을 닫지 않으면 핸들이 부족해질 수 있으며 프로그램이 충돌 할 수 있습니다. 예를 들어 stackoverflow.com/q/36990053/421049stackoverflow.com/q/26997240/421049를 참조하십시오 .
Garret Wilson

24

JDK 7에서는 Files.walkFileTree()Files.deleteIfExists()파일 트리를 삭제하는 데 사용할 수 있습니다 . (샘플 : http://fahdshariff.blogspot.ru/2011/08/java-7-deleting-directory-by-walking.html )

JDK 6에서 가능한 한 가지 방법은 Apache Commons에서 FileUtils.deleteQuietly 를 사용 하여 파일, 디렉토리 또는 파일과 하위 디렉토리가있는 디렉토리를 제거하는 것입니다.


6
다음은 샘플입니다 : fahdshariff.blogspot.ru/2011/08/…
Andrey Chaschev

23

Apache Commons-IO를 사용하면 다음과 같습니다.

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

이것은 (약간) 더 성능이 좋습니다 FileUtils.deleteDirectory.


그룹 : 'commons-io', 이름 : 'commons-io', 버전 : '2. +'-유용함
마이크 설치류

10

앞서 언급했듯이 Java는 파일이 포함 된 폴더를 삭제할 수 없으므로 먼저 파일을 삭제 한 다음 폴더를 삭제합니다.

다음은이를 수행하는 간단한 예입니다.

import org.apache.commons.io.FileUtils;



// First, remove files from into the folder 
FileUtils.cleanDirectory(folder/path);

// Then, remove the folder
FileUtils.deleteDirectory(folder/path);

또는:

FileUtils.forceDelete(new File(destination));

9

JDK의 이전 버전으로 작업하는 기본 재귀 버전 :

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}

2
디렉토리를 읽는 동안 I / O 예외가있는 경우 NullPointerException이 발생합니다. 코드 listFiles()는를 호출하는 대신 null을 반환 하는지 확인해야합니다 isDirectory().
mernst

9

다음을위한 최상의 솔루션입니다 Java 7+.

public static void deleteDirectory(String directoryFilePath) throws IOException
{
    Path directory = Paths.get(directoryFilePath);

    if (Files.exists(directory))
    {
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException
            {
                Files.delete(path);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException
            {
                Files.delete(directory);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

6

구아바 21+가 구출됩니다. 삭제할 디렉토리를 가리키는 심볼릭 링크가없는 경우에만 사용하십시오.

com.google.common.io.MoreFiles.deleteRecursively(
      file.toPath(),
      RecursiveDeleteOption.ALLOW_INSECURE
) ;

(이 질문은 Google에서 색인이 잘 생성되어 있으므로 Guava를 사용하는 다른 사람들은 다른 답변과 중복되는 경우에도이 답변을 기꺼이 찾을 수 있습니다.)


4

이 솔루션이 가장 마음에 듭니다. 타사 라이브러리를 사용하지 않고 대신 Java 7의 NIO2 를 사용합니다 .

/**
 * Deletes Folder with all of its content
 *
 * @param folder path to folder which should be deleted
 */
public static void deleteFolderAndItsContent(final Path folder) throws IOException {
    Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            if (exc != null) {
                throw exc;
            }
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
    });
}

3

한 가지 더 선택은 org.springframework.util.FileSystemUtils디렉토리의 모든 내용을 재귀 적으로 삭제하는 Spring의 관련 메소드 를 사용 하는 것입니다.

File directoryToDelete = new File(<your_directory_path_to_delete>);
FileSystemUtils.deleteRecursively(directoryToDelete);

그게 일을 할 것입니다!


2

이것에

index.delete();

            if (!index.exists())
               {
                   index.mkdir();
               }

당신은 전화하고 있습니다

 if (!index.exists())
                   {
                       index.mkdir();
                   }

index.delete();

즉, File.delete ()를 삭제 한 후 다시 파일을 생성하고 있음을 의미합니다. File.delete () 는 boolean 값을 반환합니다. 따라서 확인하고 싶다면 확인 System.out.println(index.delete());하면 true파일이 삭제되었음을 의미합니다.

File index = new File("/home/Work/Indexer1");
    if (!index.exists())
       {
             index.mkdir();
       }
    else{
            System.out.println(index.delete());//If you get true then file is deleted




            if (!index.exists())
               {
                   index.mkdir();// here you are creating again after deleting the file
               }




        }

으로부터 의견 아래, 업데이트 된 대답은 다음과 같이이다

File f=new File("full_path");//full path like c:/home/ri
    if(f.exists())
    {
        f.delete();
    }
    else
    {
        try {
            //f.createNewFile();//this will create a file
            f.mkdir();//this create a folder
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

2

하위 폴더가있는 경우 Cemron 답변에 문제가 있습니다. 따라서 다음과 같이 작동하는 메서드를 만들어야합니다.

private void deleteTempFile(File tempFile) {
        try
        {
            if(tempFile.isDirectory()){
               File[] entries = tempFile.listFiles();
               for(File currentFile: entries){
                   deleteTempFile(currentFile);
               }
               tempFile.delete();
            }else{
               tempFile.delete();
            }
        getLogger().info("DELETED Temporal File: " + tempFile.getPath());
        }
        catch(Throwable t)
        {
            getLogger().error("Could not DELETE file: " + tempFile.getPath(), t);
        }
    }

2

FileUtils.deleteDirectory 를 사용할 수 있습니다 . JAVA는 File.delete () 사용 하여 비어 있지 않은 폴더를 삭제할 수 없습니다 .


1

directry는 파일이있는 경우 단순히 삭제할 수 없으므로 먼저 내부 파일을 삭제 한 다음 디렉토리를 삭제해야 할 수 있습니다.

public class DeleteFileFolder {

public DeleteFileFolder(String path) {

    File file = new File(path);
    if(file.exists())
    {
        do{
            delete(file);
        }while(file.exists());
    }else
    {
        System.out.println("File or Folder not found : "+path);
    }

}
private void delete(File file)
{
    if(file.isDirectory())
    {
        String fileList[] = file.list();
        if(fileList.length == 0)
        {
            System.out.println("Deleting Directory : "+file.getPath());
            file.delete();
        }else
        {
            int size = fileList.length;
            for(int i = 0 ; i < size ; i++)
            {
                String fileName = fileList[i];
                System.out.println("File path : "+file.getPath()+" and name :"+fileName);
                String fullPath = file.getPath()+"/"+fileName;
                File fileOrFolder = new File(fullPath);
                System.out.println("Full Path :"+fileOrFolder.getPath());
                delete(fileOrFolder);
            }
        }
    }else
    {
        System.out.println("Deleting file : "+file.getPath());
        file.delete();
    }
}

1

하위 디렉토리가 있으면 재귀 호출을 할 수 있습니다.

import java.io.File;

class DeleteDir {
public static void main(String args[]) {
deleteDirectory(new File(args[0]));
}

static public boolean deleteDirectory(File path) {
if( path.exists() ) {
  File[] files = path.listFiles();
  for(int i=0; i<files.length; i++) {
     if(files[i].isDirectory()) {
       deleteDirectory(files[i]);
     }
     else {
       files[i].delete();
     }
  }
}
return( path.delete() );
}
}


1

JDK 클래스를 참조하는 대부분의 답변 (심지어 최근까지)은 이에 의존 File.delete()하지만 작업이 조용히 실패 할 수 있으므로 결함이있는 API입니다. 방법 문서 상태 :
java.io.File.delete()

점을 유의 java.nio.file.Files클래스가 정의 delete을 던지는 방법 IOException파일이 삭제 될 수 없을 때를. 이는 오류보고 및 파일을 삭제할 수없는 이유를 진단하는 데 유용합니다.

대신 오류 메시지가 표시 Files.delete(Path p) 되는 것을 선호해야 IOException합니다.

실제 코드는 다음과 같이 작성할 수 있습니다.

Path index = Paths.get("/home/Work/Indexer1");

if (!Files.exists(index)) {
    index = Files.createDirectories(index);
} else {

    Files.walk(index)
         .sorted(Comparator.reverseOrder())  // as the file tree is traversed depth-first and that deleted dirs have to be empty  
         .forEach(t -> {
             try {
                 Files.delete(t);
             } catch (IOException e) {
                 // LOG the exception and potentially stop the processing

             }
         });
    if (!Files.exists(index)) {
        index = Files.createDirectories(index);
    }
}

0

다음과 같이 시도 할 수 있습니다.

  File dir = new File("path");
   if (dir.isDirectory())
   {
         dir.delete();
   }

폴더 안에 하위 폴더가있는 경우이를 재귀 적으로 삭제해야 할 수 있습니다.


0
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}

0
        import org.apache.commons.io.FileUtils;

        List<String> directory =  new ArrayList(); 
        directory.add("test-output"); 
        directory.add("Reports/executions"); 
        directory.add("Reports/index.html"); 
        directory.add("Reports/report.properties"); 
        for(int count = 0 ; count < directory.size() ; count ++)
        {
        String destination = directory.get(count);
        deleteDirectory(destination);
        }





      public void deleteDirectory(String path) {

        File file  = new File(path);
        if(file.isDirectory()){
             System.out.println("Deleting Directory :" + path);
            try {
                FileUtils.deleteDirectory(new File(path)); //deletes the whole folder
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else {
        System.out.println("Deleting File :" + path);
            //it is a simple file. Proceed for deletion
            file.delete();
        }

    }

매력처럼 작동합니다. 폴더와 파일 모두. 살람 :)


-1

다른 부분에서 제거

File index = new File("/home/Work/Indexer1");
if (!index.exists())
{
     index.mkdir();
     System.out.println("Dir Not present. Creating new one!");
}
index.delete();
System.out.println("File deleted successfully");

-1

이러한 답변 중 일부는 불필요하게 길어 보입니다.

if (directory.exists()) {
    for (File file : directory.listFiles()) {
        file.delete();
    }
    directory.delete();
}

하위 디렉토리에서도 작동합니다.


-3

이 기능을 사용할 수 있습니다

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}

모든 닫힌 파일이있는 디렉토리에서 잘 작동합니다. 그러나 열린 파일이있는 디렉토리에서 시도하면 작동하지 않습니다. 당신이 날 열린 파일의 삭제 폴더 inspite 할 수있는 방법을 찾을 수 있습니다
Piyush Rumao에게

2
비어 있지 않은 하위 디렉터리는 삭제되지 않습니다.
Pang
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.