WatchService

      在web中很多时候,我们会把文件存放在文件夹中,为了查询的效率,会加上Lucene索引等。一般就是在执行过程中另起线程对Lucene索引进行维护。这里介绍另外一个方法: WatchService。这是Java SE 7自带的监控服务。

    代码如下:

package com.jdk7.watch;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
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.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Timer;
import java.util.TimerTask;

public class TestWatcherService {
    private WatchService watchService;

    public TestWatcherService(String dir) throws IOException {
        Path path = Paths.get(dir);
        watchService = FileSystems.getDefault().newWatchService();
        registerAll(path);

    }
    void registerAll(Path path) throws IOException {
        if (Files.isDirectory(path)) {
            Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path dir,
                        BasicFileAttributes attrs) throws IOException {
                    register(dir);
                    return FileVisitResult.CONTINUE;
                }
            });
        } 
    }

    private void register(Path path) throws IOException {
        System.err.printf("Path :[%s] will be registered.\n" , path);
        path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE,
                StandardWatchEventKinds.ENTRY_MODIFY);
        System.err.printf("Path :[%s] registered success.\n" , path);
    }

    public void handleEvents() {
        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    WatchKey key = watchService.take();
                    for (WatchEvent<?> event : key.pollEvents()) {
                        Kind<?> kind = event.kind();
                        if (StandardWatchEventKinds.OVERFLOW.equals(kind)){
                            continue;
                        }
                        WatchEvent<?> e = (WatchEvent<?>) event;
                        Path fileName = (Path) e.context();
                        System.out.printf(
                                "Event %s has happened,which fileName is %s%n",
                                kind.name(), fileName);
                    }
                    if(!key.reset()){
                        timer.cancel();
                    }
                } catch (InterruptedException e1) {
                    timer.cancel();
                    e1.printStackTrace();
                }
            }
        }, 100,5);
    }

    public static void main(String[] args) throws InterruptedException,
            IOException {
        new TestWatcherService("/home/guest/桌面").handleEvents();
    }
}

这样就可以监控/home/guest/桌面目录下所有的文件夹内容的修改。但是这个里面有一个缺点就是:  Path fileName = (Path) e.context(); 获取的Path 无法得到真是的路径。但是一般而言只是单一目录下的文件不需要这样了。

    这样就可以在handleEvents中处理索引事件。不需要在代码中另起线程,导致代码过长。充分的解耦和。

你可能感兴趣的:(WatchService)