DirectoryStream<T> — 디렉터리의 항목을 반복하는 객체
DirectoryStream — 디렉터리의 항목을 반복하는 객체
DirectoryStream<T>는 디렉터리의 항목(entry)을 반복하는 객체예요. 디렉터리 스트림은 for-each 구문을 사용해 디렉터리를 편리하게 반복할 수 있게 해줘요.
본문
public interface DirectoryStream<T> extends Closeable, Iterable<T>
디렉터리의 항목을 반복하는 객체예요. 디렉터리 스트림은 for-each 구문을 편리하게 사용해 디렉터리를 반복할 수 있게 해줘요.
DirectoryStream은 Iterable을 확장하지만 단일 Iterator만 지원하므로 범용 Iterable은 아니에요. 두 번째나 그 이후의 Iterator를 얻기 위해 iterator 메서드를 호출하면 IllegalStateException을 던져요.
디렉터리 스트림의 Iterator의 중요한 속성은 hasNext 메서드가 적어도 한 요소를 미리 읽어(read-ahead) 들임이 보장된다는 점이에요. hasNext가 true를 반환하고 이어서 next 메서드를 호출하면, next가 I/O 오류나 스트림이 닫혔기 때문에 예외를 던지지 않음이 보장돼요. Iterator는 remove 연산을 지원하지 않아요.
DirectoryStream은 생성 시 열리고 close 메서드를 호출해 닫아요. 디렉터리 스트림을 닫지 않으면 리소스 누수가 발생할 수 있어요. try-with-resources 구문이 스트림이 닫히도록 보장하는 유용한 구문이에요:
Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry: stream) {
...
}
}
이터레이터가 반환하는 요소는 특정한 순서가 없어요. 이터레이터는 약하게 일관적(weakly consistent)이에요. 스레드 안전하지만 반복하는 동안 디렉터리를 고정(freeze)하지 않아서, DirectoryStream 생성 후 발생하는 디렉터리 갱신을 반영할 수도 있고 아닐 수도 있어요.
사용 예
List<Path> listSourceFiles(Path dir) throws IOException {
List<Path> result = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
for (Path entry: stream) {
result.add(entry);
}
} catch (DirectoryIteratorException ex) {
// 반복 중 발생한 I/O 오류, 원인은 IOException
throw ex.getCause();
}
return result;
}
중첩 인터페이스
static interface DirectoryStream.Filter<T> — 디렉터리 항목을 받을지 필터링할지 결정하는 객체가 구현하는 인터페이스
메서드 요약
| 수식자와 타입 | 메서드 | 설명 |
|---|---|---|
Iterator<T> |
iterator() |
이 DirectoryStream과 연관된 이터레이터를 반환해요. |
Closeable에 선언된 메서드: close, Iterable에 선언된 메서드: forEach, spliterator
iterator
Iterator<T> iterator() — 이 DirectoryStream과 연관된 이터레이터를 반환해요. Iterable의 iterator에 의해 지정돼요. 디렉터리 스트림이 닫혀 있거나 이터레이터가 이미 반환된 경우 IllegalStateException을 던져요.