1. 개요
이 기사에서는 NIO2의 흥미로운 기능인 FileVisitor 인터페이스 를 살펴보겠습니다 .
모든 운영 체제와 여러 타사 응용 프로그램에는 사용자가 검색 기준을 정의하는 파일 검색 기능이 있습니다.
이 인터페이스는 Java 애플리케이션에서 이러한 기능을 구현하는 데 필요한 것입니다. 모든 .mp3 파일 을 검색해야 하거나 .class 파일을 찾아서 삭제해야 하거나 지난 달에 액세스하지 않은 모든 파일을 찾아야 하는 경우 이 인터페이스가 필요합니다.
이 기능을 구현하는 데 필요한 모든 클래스는 하나의 패키지에 번들로 제공됩니다.
import java.nio.file.*;
2. FileVisitor 작동 방식
으로 FileVisitor의 인터페이스, 당신은 어떤 깊이로 파일 트리를 탐색하고 파일이나 디렉토리에 대한 모든 작업을 수행 할 어떤 지점에서 찾을 수 있습니다.
FileVisitor 인터페이스 의 일반적인 구현은 다음과 같습니다.
public class FileVisitorImpl implements FileVisitor<Path> {
@Override
public FileVisitResult preVisitDirectory(
Path dir, BasicFileAttributes attrs) {
return null;
}
@Override
public FileVisitResult visitFile(
Path file, BasicFileAttributes attrs) {
return null;
}
@Override
public FileVisitResult visitFileFailed(
Path file, IOException exc) {
return null;
}
@Override
public FileVisitResult postVisitDirectory(
Path dir, IOException exc) {
return null;
}
}
네 가지 인터페이스 방법을 사용하면 순회 프로세스의 주요 지점에서 필요한 동작을 지정할 수 있습니다. 디렉토리에 액세스하기 전, 파일을 방문할 때 또는 오류가 발생할 때와 디렉토리에 각각 액세스한 후입니다.
각 단계의 반환 값은 FileVisitResult 유형 이며 순회 흐름을 제어합니다. 특정 디렉토리를 찾기 위해 파일 트리를 탐색하고 발견되면 프로세스를 종료하거나 특정 디렉토리나 파일을 건너뛰고 싶을 수 있습니다.
FileVisitResult 는 FileVisitor 인터페이스 메서드에 대한 네 가지 가능한 반환 값의 열거형입니다 .
- FileVisitResult.CONTINUE – 반환하는 메서드가 종료된 후 파일 트리 탐색이 계속되어야 함을 나타냅니다.
- FileVisitResult.TERMINATE – 파일 트리 탐색을 중지하고 더 이상 디렉터리나 파일을 방문하지 않습니다.
- FileVisitResult.SKIP_SUBTREE – 이 결과는 preVisitDirectory API에서 반환될 때만 의미가 있으며, 다른 곳에서는 CONTINUE 처럼 작동합니다. 현재 디렉토리와 모든 하위 디렉토리를 건너뛰어야 함을 나타냅니다.
- FileVisitResult.SKIP_SIBLINGS – 순회가 현재 파일이나 디렉터리의 형제를 방문하지 않고 계속되어야 함을 나타냅니다. preVisitDirectory 단계에서 호출하면 현재 디렉터리도 건너뛰고 postVisitDirectory 가 호출되지 않습니다.
마지막으로 사용자가 검색 기준을 정의한 후 그래픽 사용자 인터페이스에서 검색 버튼을 클릭할 때 순회 프로세스를 트리거하는 방법이 있어야 합니다. 이것은 가장 간단한 부분입니다.
Files 클래스 의 정적 walkFileTree API 를 호출 하고 순회 시작점을 나타내는 Path 클래스 의 인스턴스와 FileVisitor 의 인스턴스를 전달하기만 하면 됩니다 .
Path startingDir = Paths.get("pathToDir");
FileVisitorImpl visitor = new FileVisitorImpl();
Files.walkFileTree(startingDir, visitor);
3. 파일 검색 예
이 섹션에서는 FileVisitor 인터페이스를 사용하여 파일 검색 응용 프로그램을 구현합니다 . 우리는 사용자가 확장자를 가진 완전한 파일 이름과 찾고자 하는 시작 디렉토리를 지정할 수 있도록 하고 싶습니다.
파일을 찾으면 성공 메시지를 화면에 출력하고 파일을 찾지 못한 상태에서 전체 파일 트리를 검색하면 적절한 실패 메시Map 출력한다.
3.1. 메인 클래스
이 클래스를 FileSearchExample.java 라고 부를 것입니다 .
public class FileSearchExample implements FileVisitor<Path> {
private String fileName;
private Path startDir;
// standard constructors
}
우리는 아직 인터페이스 메소드를 구현하지 않았습니다. 검색할 파일의 이름과 검색을 시작할 경로를 사용하는 생성자를 만들었습니다. 파일을 찾지 못했다는 결론을 내리기 위한 기본 사례로만 시작 경로를 사용합니다.
다음 하위 섹션에서 각 인터페이스 메서드를 구현하고 이 특정 예제 응용 프로그램에서의 역할에 대해 설명합니다.
3.2. preVisitDirectory API
preVisitDirectory API 를 구현하여 시작하겠습니다 .
@Override
public FileVisitResult preVisitDirectory(
Path dir, BasicFileAttributes attrs) {
return CONTINUE;
}
앞에서 말했듯이 이 API는 프로세스가 트리에서 새 디렉토리를 만날 때마다 호출됩니다. 반환 값은 우리가 결정한 것에 따라 다음에 일어날 일을 결정합니다. 이것은 특정 디렉토리를 건너뛰고 검색 샘플 공간에서 제거하는 지점입니다.
디렉토리를 구별하지 않고 모든 디렉토리를 검색하도록 합시다.
3.3. visitFile의 API
다음으로 visitFile API를 구현합니다 . 여기에서 주요 작업이 발생합니다. 이 API는 파일을 만날 때마다 호출됩니다. 이를 활용하여 파일 속성을 확인하고 기준과 비교하여 적절한 결과를 반환합니다.
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
String fileName = file.getFileName().toString();
if (FILE_NAME.equals(fileName)) {
System.out.println("File found: " + file.toString());
return TERMINATE;
}
return CONTINUE;
}
우리의 경우 사용자가 검색하는 파일인지 확인하기 위해 방문 중인 파일의 이름만 확인합니다. 이름이 일치하면 성공 메시지를 출력하고 프로세스를 종료합니다.
그러나 특히 파일 속성 섹션을 읽은 후에는 여기에서 할 수 있는 일이 너무 많습니다 . 생성 시간, 마지막 수정 시간 또는 마지막 액세스 시간 또는 attrs 매개변수 에서 사용 가능한 여러 속성을 확인 하고 그에 따라 결정할 수 있습니다.
3.4. visitFileFailed의 API
다음으로 visitFileFailed API를 구현합니다 . 이 API는 JVM에서 특정 파일에 액세스할 수 없을 때 호출됩니다. 다른 응용 프로그램에 의해 잠겨 있거나 권한 문제일 수 있습니다.
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
System.out.println("Failed to access file: " + file.toString());
return CONTINUE;
}
우리는 단순히 실패 메시지를 기록하고 나머지 디렉토리 트리 탐색을 계속합니다. 그래픽 응용 프로그램 내에서 대화 상자를 계속 사용할지 여부를 사용자에게 묻거나 메시지를 어딘가에 기록하고 나중에 사용하기 위해 보고서를 컴파일하도록 선택할 수 있습니다.
3.5. postVisitDirectory API
마지막으로 postVisitDirectory API를 구현합니다 . 이 API는 디렉토리가 완전히 탐색될 때마다 호출됩니다.
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc){
boolean finishedSearch = Files.isSameFile(dir, START_DIR);
if (finishedSearch) {
System.out.println("File:" + FILE_NAME + " not found");
return TERMINATE;
}
return CONTINUE;
}
Files.isSameFile API를 사용하여 방금 통과한 디렉터리가 탐색을 시작한 디렉터리인지 확인합니다. 반환 값이 true 이면 검색이 완료되었으며 파일을 찾지 못했다는 의미입니다. 그래서 우리는 실패 메시지와 함께 프로세스를 종료합니다.
그러나 반환 값이 false 이면 하위 디렉터리 탐색을 막 마쳤으며 다른 하위 디렉터리에서 파일을 찾을 가능성이 여전히 있음을 의미합니다. 그래서 우리는 순회를 계속합니다.
이제 FileSearchExample 애플리케이션 을 실행하기 위한 기본 메서드를 추가할 수 있습니다 .
public static void main(String[] args) {
Path startingDir = Paths.get("C:/Users/user/Desktop");
String fileToSearch = "hibernate-guide.txt"
FileSearchExample crawler = new FileSearchExample(
fileToSearch, startingDir);
Files.walkFileTree(startingDir, crawler);
}
당신의 값을 변경하여이 예를 놀러 수 startingDir 및 fileToSearch 변수를. 때 fileToSearch가 존재 startingDir 또는 하위 디렉토리의, 당신은 다른 성공 메시지, 오류 메시지가 표시됩니다.
4. 결론
이 기사에서는 Java 7 NIO.2 파일 시스템 API, 특히 FileVisitor 인터페이스 에서 사용할 수 있는 덜 일반적으로 사용되는 기능을 살펴보았습니다 . 우리는 또한 그 기능을 시연하기 위해 파일 검색 애플리케이션을 구축하는 단계를 거쳤습니다.
이 기사에 사용된 예제의 전체 소스 코드는 Github 프로젝트 에서 사용할 수 있습니다 .