본문으로 바로가기

JAVA의 WatchService에서 주의할점

category Language/자바 2023. 8. 10. 15:22
728x90
반응형
SMALL

JAVA의 WatchService에서 주의할점

WatchServiceListener.class

@Slf4j
@Component
public class WatchServiceListener implements InitializingBean {

    @Value("${file.watch.path}")
    private static String filePath;

    @Autowired
    private WatchProperties watchProperties;
    private WatchKey watchKey;

    @Override
    public void afterPropertiesSet() throws Exception {
        //watchService 생성
        WatchService watchService = FileSystems.getDefault().newWatchService();
        //경로 생성
        Path path = Paths.get(watchProperties.getWatch().getPath());
        File file = path.toFile();
        //해당 디렉토리 경로에 와치서비스와 이벤트 등록
        path.register(watchService,
        	StandardWatchEventKinds.ENTRY_CREATE,
            StandardWatchEventKinds.ENTRY_DELETE,
            StandardWatchEventKinds.ENTRY_MODIFY,
            StandardWatchEventKinds.OVERFLOWY);

        Thread thread = new Thread(()-> {
            while(true) {
                try {
                    watchKey = watchService.take();//이벤트가 오길 대기(Blocking)
                    //파일 수정시, 수정시간, 저장시간으로 인해서 같은 이벤트의 발생이 중복으로 일어나는데
                    //지연을 주면 중복을 방지 할 수 있음
                    Thread.sleep( 50 );
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                List<WatchEvent<?>> events = watchKey.pollEvents();//이벤트들을 가져옴
                for(WatchEvent<?> event : events) {
                    //이벤트 종류
                    Kind<?> kind = event.kind();

                    //경로
                    Path paths = (Path)event.context();
                    log.info(paths.toAbsolutePath().toString());

                    Path eventPath = (Path) event.context();
                    File targetFile = ((Path) watchKey.watchable()).resolve(eventPath).toFile();

                    if (targetFile.getName().equals("application.yml")){ //특정 파일 이름 감시
                        if(kind.equals(StandardWatchEventKinds.ENTRY_CREATE)) {
                            System.out.println("created something in directory");
                        }else if(kind.equals(StandardWatchEventKinds.ENTRY_DELETE)) {
                            System.out.println("delete something in directory");
                        }else if(kind.equals(StandardWatchEventKinds.ENTRY_MODIFY)) {
                            System.out.println("modified something in directory");
                        }else if(kind.equals(StandardWatchEventKinds.OVERFLOW)) {
                            System.out.println("overflow");
                        }
                    }
                }
                if(!watchKey.reset()) {
                    try {
                        watchService.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread.start();
    }
}

application.yml

file:
  watch:
    path: /apps/test

WatchService에서 파일명이 아닌 폴더명으로 지정했을 경우

Win에서 해당 폴더 아래에 파일을 `변경`하는경우 create update delete 를 구분하여 update event만 catch 하지만

Linux인 경우 인식하는 바와 조금 다를수 있다,


Linux에서 vi,vim 에디터로 편집(update)시 .swp, .swx 파일이 create 되고 저 본 파일이 저장이 완료되면 update 되고 .swp, .swx파일들이 delete 되기 때문에 편집 이라는 행위하나로3가지의 이벤트(create, update, delete)가 발생한다

 

이는 혼란을 줄수 있으니 주의하자.

728x90
반응형
LIST