1. 소개

이 기사에서는 일반 Java에서 재귀 적으로 디렉토리를 삭제하는 방법을 설명합니다. 또한 외부 라이브러리를 사용하여 디렉토리를 삭제하는 몇 가지 대안을 살펴 보겠습니다.

2. 재귀 적으로 디렉토리 삭제

Java에는 디렉토리를 삭제하는 옵션이 있습니다. 그러나이를 위해서는 디렉토리가 비어 있어야합니다. 따라서 비어 있지 않은 특정 디렉토리를 삭제하려면 재귀를 사용해야합니다.

  1. 삭제할 디렉토리의 모든 내용을 가져옵니다.
  2. 디렉토리가 아닌 모든 하위 항목 삭제 (재귀에서 종료)
  3. 현재 디렉터리의 각 하위 디렉터리에 대해 1 단계 (반복 단계)부터 시작합니다.
  4. 디렉토리 삭제

이 간단한 알고리즘을 구현해 보겠습니다.

boolean deleteDirectory(File directoryToBeDeleted) {
    File[] allContents = directoryToBeDeleted.listFiles();
    if (allContents != null) {
        for (File file : allContents) {
            deleteDirectory(file);
        }
    }
    return directoryToBeDeleted.delete();
}

이 방법은 간단한 테스트 케이스를 사용하여 테스트 할 수 있습니다.

@Test
public void givenDirectory_whenDeletedWithRecursion_thenIsGone() 
  throws IOException {
 
    Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME);

    boolean result = deleteDirectory(pathToBeDeleted.toFile());

    assertTrue(result);
    assertFalse(
      "Directory still exists", 
      Files.exists(pathToBeDeleted));
}

@Before의 우리의 테스트 클래스의 방법은 하위 디렉토리와 파일이있는 디렉토리 트리 생성 pathToBeDeleted의 위치와 @After에 필요한 경우 방법은 디렉토리를 정리합니다.

다음으로, 가장 일반적으로 사용되는 두 라이브러리 인 Apache의 commons-io 와 Spring Framework의 spring-core를 사용하여 삭제를 달성하는 방법을 살펴 보겠습니다 . 이 두 라이브러리를 사용하면 한 줄의 코드로 디렉토리를 삭제할 수 있습니다.

3. commons-io 에서 FileUtils 사용

먼저 Maven 프로젝트에 commons-io 의존성을 추가해야합니다 .

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>

최신 버전의 의존성은 여기 에서 찾을 수 있습니다 .

이제 FileUtils사용 하여 하나의 명령문으로 deleteDirectory ()포함한 모든 파일 기반 작업을 수행 할 수 있습니다 .

FileUtils.deleteDirectory(file);

4. Spring에서 FileSystemUtils 사용

또는 Maven 프로젝트에 s pring-core 의존성을 추가 할 수 있습니다 .

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.10.RELEASE</version>
</dependency>

최신 버전의 의존성은 여기 에서 찾을 수 있습니다.

우리는 사용할 수 deleteRecursively () 메서드 FileSystemUtils을 삭제를 수행 할 수 :

boolean result = FileSystemUtils.deleteRecursively(file);

최신 Java 릴리스는 다음 섹션에서 설명하는 이러한 IO 작업을 수행하는 새로운 방법을 제공합니다.

5. Java 7과 함께 NIO2 사용

Java 7은 Files를 사용하여 파일 작업을 수행하는 완전히 새로운 방법을 도입했습니다 . 이를 통해 디렉토리 트리를 탐색하고 수행 할 작업에 대한 콜백을 사용할 수 있습니다.

public void whenDeletedWithNIO2WalkFileTree_thenIsGone() 
  throws IOException {
 
    Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME);

    Files.walkFileTree(pathToBeDeleted, 
      new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult postVisitDirectory(
          Path dir, IOException exc) throws IOException {
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
        
        @Override
        public FileVisitResult visitFile(
          Path file, BasicFileAttributes attrs) 
          throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }
    });

    assertFalse("Directory still exists", 
      Files.exists(pathToBeDeleted));
}

Files.walkFileTree () 메소드는 파일 트리를 방출 이벤트를 통과. 이러한 이벤트에 대한 콜백을 지정해야합니다. 따라서이 경우 생성 된 이벤트에 대해 다음 작업을 수행하도록 SimpleFileVisitor정의 합니다.

  1. 파일 방문 – 삭제
  2. 항목을 처리하기 전에 디렉토리 방문 – 아무 작업도하지 않음
  3. 항목을 처리 한 후 디렉토리 방문-디렉토리를 삭제하십시오.이 디렉토리 내의 모든 항목은 지금까지 처리 (또는 삭제)되었을 것입니다.
  4. 파일을 방문 할 수 없습니다 . 실패를 일으킨 IOException 을 다시 발생시킵니다.

파일 작업 처리에 대한 NIO2 API에 대한 자세한 내용 은 Java NIO2 파일 API 소개를 참조하십시오 .

6. Java 8에서 NIO2 사용

Java 8부터 Stream API는 디렉토리를 삭제하는 더 나은 방법을 제공합니다.

@Test
public void whenDeletedWithFilesWalk_thenIsGone() 
  throws IOException {
    Path pathToBeDeleted = TEMP_DIRECTORY.resolve(DIRECTORY_NAME);

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

    assertFalse("Directory still exists", 
      Files.exists(pathToBeDeleted));
}

여기서 Files.walk ()역순으로 정렬 한 경로 스트림반환합니다 . 이것은 디렉토리 자체 앞에 디렉토리의 내용을 나타내는 경로를 배치합니다. 그 후 Path to File을 매핑 하고 각 파일을 삭제합니다 .

7. 결론

이 빠른 사용방법(예제)에서는 디렉터리를 삭제하는 다양한 방법을 살펴 보았습니다. 재귀를 사용하여 삭제하는 방법을 확인하는 동안 일부 라이브러리, 이벤트를 활용하는 NIO2 및 기능 프로그래밍 패러다임을 사용하는 Java 8 Path Stream도 살펴 보았습니다.

이 기사의 모든 소스 코드와 테스트 케이스는 GitHub에서 사용할 수 있습니다 .