如何从线程watchservice返回值

时间:2015-03-12 12:13:09

标签: java

我有一个类在特定文件夹中查找已移动到那里的新图像文件。如何将这些文件的名称返回给我的主类,以便我们可以在将图像移入文件夹后对其进行操作?

在我的主要课程中我有

Thread thread = new Thread(new DirectoryWatcher(directory.toPath()));
thread.start();

和DirectoryWatcher类

public class DirectoryWatcher implements Runnable{

private Path path;
private FileSystem fs;
private WatchKey watchKey;
private Path newFile;
private static final Pattern pattern = Pattern.compile("[A-Za-z0-9-_\\s()]+.(jpg|png|bmp|JPG|PNG|BMP)");
private Matcher matcher;
private String patternMatcher;

public DirectoryWatcher(Path path){

    this.path = path;
    fs = this.path.getFileSystem();
    watchKey = null;

}

@Override
public void run() {
    try{
        Boolean isFolder = (boolean) Files.getAttribute(path, "basic:isDirectory", NOFOLLOW_LINKS);
        if(!isFolder) {
            throw new IllegalArgumentException("Path: " + path + " is not a folder");
        }
    } catch (IOException e){
        e.printStackTrace();
    }

    System.out.println("Watching directory: " + path);

    try(WatchService service = fs.newWatchService()) {
        path.register(service, ENTRY_CREATE);

        //WatchKey watchKey = null;
        while(true) {
            watchKey = service.take();

            Kind<?> kind = null;
            for(WatchEvent<?> watchEvent : watchKey.pollEvents()){
                kind = watchEvent.kind();
                if(OVERFLOW == kind) {
                    continue;
                } else if (ENTRY_CREATE == kind){
                    newFile = ((WatchEvent<Path>) watchEvent).context();
                    patternMatcher = newFile.toString();
                    matcher = pattern.matcher(patternMatcher);
                    //
                    //If the file is an image
                    if(matcher.matches()){
                        //Return image to main class
                    }
                }
            }
            if (!watchKey.reset()){
                break;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e){
        e.printStackTrace();
    }
}

}

1 个答案:

答案 0 :(得分:0)

嗯,我不确定,但我认为你应该从DirectoryWatcher线程本身或者从DirectoryWatcher线程创建的其他线程(Callable)操作图像。
在最后一个场景中,只要在文件夹中检测到新图像,DirectoryWatcher就会启动一个线程(可调用)。每个创建的线程只会使用新文件完成工作,然后终止。为了做到这一点,我建议你看一下ExecutorService,Callable和Future。使用该API,您将无需担心线程同步。

否则,如果你真的希望主线程每次目录观察者找到新图像时都做某事,你的主线程必须首先创建一个阻塞集合,如ArrayBlockingQueue,将它传递给DirectoryWatcher线程在开始之前。 然后,DirectoryWatcher线程会在需要时将文件名添加到队列中,并且主线程可以永远循环,调用阻塞队列的take()方法。 请记住,如果你这样做,主线程除了监听从DirectoryWatcher返回的文件名外什么都不做。
并且因为对于找到的所有文件只有一个执行的线程,所以与上面提出的ExecutorService,Callable,Future的解决方案相比,在同时复制多个图像的情况下,其效果会更差。