파일 시스템을 다루다 보면 특정 폴더 안에 있는 빈 디렉토리(empty directory)의 이름만 골라내야 하는 경우가 종종 있습니다. Java에서는 File 클래스의 listFiles() 메서드와 FileFilter 인터페이스를 조합하면 이 작업을 아주 간단하게 처리할 수 있습니다.
listFiles() 메서드와 FileFilter 이해하기
listFiles() 메서드는 현재 File 객체가 가리키는 경로에 존재하는 모든 파일과 디렉토리에 대한 추상 경로(abstract pathname) 객체를 배열 형태로 반환합니다.
FileFilter 인터페이스는 경로 이름을 걸러 주는 필터 역할을 합니다. 이 필터를 listFiles() 메서드의 매개변수로 전달하면, 지정한 조건을 만족하는 파일과 디렉토리만 결과 배열에 포함됩니다.
구현 절차
1. 대상 폴더를 나타내는 File 객체를 생성합니다.
2. "디렉토리이면서 내부가 비어 있는 경우"에만 true를 반환하는 FileFilter를 익명 클래스로 구현합니다.
3. 이 필터를 listFiles() 메서드에 전달하여 결과 배열을 얻습니다.
예제 코드
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
public class MyExample {
public static void main(String args[]) throws IOException {
// 대상 디렉토리를 나타내는 File 객체 생성
File directoryPath = new File("D:\\ExampleDirectory");
// 빈 디렉토리만 허용하는 필터 생성
FileFilter fileFilter = new FileFilter() {
public boolean accept(File dir) {
if (dir.isDirectory() && dir.list().length == 0) {
return true;
} else {
return false;
}
}
};
File[] list = directoryPath.listFiles(fileFilter);
System.out.println("지정된 디렉토리 내의 빈 디렉토리 목록:");
for (File fileName : list) {
System.out.println(fileName.getName());
System.out.println(fileName);
}
}
}
여기서 핵심은 accept() 메서드의 조건입니다. dir.isDirectory()로 해당 항목이 디렉토리인지 먼저 확인하고, dir.list().length == 0으로 내부에 파일이나 하위 디렉토리가 하나도 없는지 검사합니다. 두 조건을 모두 만족하는 항목만 최종 목록에 남게 됩니다.
실행 결과
지정된 디렉토리 내의 빈 디렉토리 목록: sample directory1 D:\ExampleDirectory\sample directory1
참고: 람다 표현식으로 더 간결하게
Java 8 이상을 사용한다면 함수형 인터페이스인 FileFilter를 람다 표현식으로 대체할 수 있어 코드가 한층 짧아집니다.
File[] list = directoryPath.listFiles(dir -> dir.isDirectory() && dir.list().length == 0);
또한 listFiles()는 I/O 오류나 접근 권한 문제가 발생하면 null을 반환할 수 있으므로, 실무 환경에서는 반드시 반환값의 null 여부를 검사한 뒤 배열을 순회하는 것이 안전합니다.