WatchService(와치서비스)
- 디렉토리 내부에서 파일 생성, 수정, 삭제 등의 내용 변화를 감시하는데 사용. (파일변경 통지 매커니즘으로알려짐)
ex) 텍스트 에디터
1. 생성
WatchService watchService = FileSystems.getDefault().newWatchService();
Path 객체에서 register() 메소드에 watchService를 등록하고
어떤 변화(생성, 삭제, 수정)를 감시할 것인지 StandardWatchEventKinds을 지정한다.
2. 감시자 지정
Path path = Paths.get("d:/test");
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
디렉토리에 WatchService를 등록한 순간부터 디렉토리 내부에서 변경이 발생하면 WatchEvent가 발생하고, WatchService는 해당 이벤트 정보를 가진 와치키(WatchKey)를 생성하여 큐(queue)에 넣어준다.
프로그램은 루프를 돌면서 WatchService의 take() 메서드를 호출하여 WatchKey가 들어올 때까지 대기하고 있다가 WatchKey가 큐에들어오면 WatchKey를 얻어 처리하면 된다.
3. 서비스 실행
while(true) {
WatchKey key = watchService.take();
}
WatchKey를 얻고 pollEvents() 메소드를 호출해서 WatchEvent 리스트를 가져온다.
List<WatchEvent<?>>로 리턴하는 이유는 동시에 생성, 수정, 삭제가 발생할 수 있기 때문이다.
4. eventPool 호출
List<WatchEvent<?>> eventList = key.pollEvents();
WatchEvent 리스트에서 WatchEvent를 하나씩 꺼내어 이벤트의 종류와 Path 객체를 얻어내고 처리한다.
5. 이벤트 처리
for (WatchEvent<?> event : eventList) {
//이벤트의 종류
Kind<?> kind = event.kind();
//감지된 Path
Path path = (Path)event.context();
//이벤트 종류별로 처리
if (kind.equals(StandardWatchEventKinds.ENTRY_CREATE)) {
// 생성되었을 경우, 실행할 코드
} else if(kind.equals(StandardWatchEventKinds.ENTRY_DELETE)) {
// 삭제되었을 경우, 실행할 코드
} else if (kind.equals(StandardWatchEventKinds.ENTRY_MODIFY)) {
// 수정되었을경우, 실행할 코드
} else if (kind.equals(StandardWatchEventKinds.OVERFLOW)) {
//운영체제에서 이벤트가 소실되었거나 버려진 경우에 발생
}
}
한 번 사용된 WatchKey 는 reset() 메소드로 초기화해야한다.
이유는 새로운 WatchEvent가 발생하면 큐에 다시들어가기 때문이다.
초기화에 성공시 true를 반환하고 감시하는 디렉토리가 삭제나 키가 더이상 유효하지 않을 경우 false를 반환한다.
WatchKey가 더이상 유효하지 않게되면 루프를 빠져나와 WatchService close() 메소드를 호출하고 종료한다.
while(true) {
WatchKey key = watchService.take();
List<WatchEvent<?>> eventList = key.pollEvents();
for (WatchEvent<?> event : eventList) {
//이벤트의 종류
Kind<?> kind = event.kind();
//감지된 Path
Path path = (Path)event.context();
//이벤트 종류별로 처리
if (kind.equals(StandardWatchEventKinds.ENTRY_CREATE)) {
// 생성되었을 경우, 실행할 코드
} else if(kind.equals(StandardWatchEventKinds.ENTRY_DELETE)) {
// 삭제되었을 경우, 실행할 코드
} else if (kind.equals(StandardWatchEventKinds.ENTRY_MODIFY)) {
// 수정되었을경우, 실행할 코드
} else if (kind.equals(StandardWatchEventKinds.OVERFLOW)) {
//운영체제에서 이벤트가 소실되었거나 버려진 경우에 발생
}
}
boolean valid = key.reset();
if (!valid) {
break;
}
}
watchService.close();
'Language > Java' 카테고리의 다른 글
비동기 파일채널 (0) | 2017.03.29 |
---|---|
NIO (0) | 2017.03.29 |
규칙 2. 생성자 인자가 많을 때는 Builder 패턴 적용을 고려하라 (0) | 2017.01.19 |
규칙 1. 생성자대신 정적 팩터리 메서드를 사용할 수 없는지 생각해 보라 (0) | 2017.01.19 |
[병렬처리]2. 스레드의 안전성 (0) | 2016.12.12 |