자바에서 WatchService라는 기능을 사용하여 특정 디렉토리를 모니터링하여 디렉토리(폴더)에 파일이 생성,변경,삭제 되는 것을 감시하고 있다가 'test'라는 파일명으로 파일이 생성되면 해당 파일 정보를 출력하는 프로그램을 만들려고 한다.

 

import java.io.File;
import java.io.IOException;
import java.nio.file.ClosedWatchServiceException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class watchService {

    public Boolean isStart = true;

    public static void main(String[] args) {
    	Path path = Paths.get("C:\\sample");
        try {
            System.out.println("WatchService START");
            monitoring(path);
            System.out.println("WatchService END");
        } catch (IOException | InterruptedException e) {
        	System.out.println(e);
        }
    }

    private static WatchService watchService;
    private static WatchKey watchKey;
    private final static Map<WatchKey, Path> directories = new HashMap<>();

    private static void registerTree(Path start) throws IOException {
        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                WatchKey key = dir.register(watchService
                		, StandardWatchEventKinds.ENTRY_CREATE //생성
                		, StandardWatchEventKinds.ENTRY_MODIFY //변경
                		, StandardWatchEventKinds.ENTRY_DELETE); //삭제
                directories.put(key, dir);
                return FileVisitResult.CONTINUE;
            }
        });
    }

    public static void monitoring(Path watchPath) throws IOException, InterruptedException,ClosedWatchServiceException {
    	System.out.println("monitoring START");
        watchService = FileSystems.getDefault().newWatchService(); // watchService 생성
        registerTree(watchPath);

        //Thread thread = new Thread(() -> {
            while (true) {
                try {
                    watchKey = watchService.take(); // 이벤트가 오길 대기(Blocking)
                } catch (InterruptedException e) {
                	System.out.println(e);
                }catch(ClosedWatchServiceException e){
                	return; 
                	//LOGGER.error("{}", e);
                }
                Path dir = directories.get(watchKey);
                if (dir == null) {
                	System.out.println("WatchKey not recognized!!");
                    continue;
                }

                for (WatchEvent<?> watchEvent : watchKey.pollEvents()) { // 이벤트들을 가져옴
                    Kind<?> kind = watchEvent.kind(); // 이벤트 종류
                    WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent;
                    Path filename = watchEventPath.context();

                    if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                        Path directory_path = directories.get(watchKey);
                        Path child = directory_path.resolve(filename);
                        File file = child.toFile();

                        if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) {
                            try {
                                registerTree(child);
                            } catch (IOException e) {
                            	System.out.println(e);
                            }
                        }

                        // 파일 확인
                        if (file.isFile() && file.getName().matches(".*test.*")) {
                    		System.out.println("===========================================================");
                    		System.out.println("파일 발견 : " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.KOREA).format(new java.util.Date()));
                    		System.out.println("파일명 : "+file.getName());
                    		System.out.println("파일경로 : "+file.getParent());
                    		System.out.println("-----------------------------------------------------------");
                        	
                        }


                    } else if (kind.equals(StandardWatchEventKinds.ENTRY_DELETE)) {
                    	System.out.println("delete something in directory");
                    } else if (kind.equals(StandardWatchEventKinds.ENTRY_MODIFY)) {
                    	System.out.println("modify something in directory");
                    } else if (kind.equals(StandardWatchEventKinds.OVERFLOW)) {
                    	System.out.println("overflow");
                        continue;
                    } else {
                    	System.out.println("test");
                    }
                }

                boolean valid = watchKey.reset();
                if (!valid) {
                	directories.remove(watchKey);

                    if (directories.isEmpty()) {
                        break;
                    }
                }
            }
            try {
            	System.out.println("WatchService close");
				watchService.close();
			} catch (IOException e) {
				System.out.println(e);
			}
       // });
       // thread.start();
        System.out.println("monitoring END");
    }

  

}

 

위에 소스를 돌려보면 'test'가 들어간 파일이 특정 경로에 생성될 때 아래와 같은 로그가 콘솔에 찍히는 것을 확인할 수 있다.

 

[결과]

+ Recent posts