WatchService如果没有事件在目录中发生,则在API中有任何构建



我想问你一个有关 WatchService的问题。因此,我有代码在目录中出现时正在重命名特定文件。但是我想设置WatchService的超时运行时间,如果目录内什么都没发生。

,但是我从我阅读的内容中。有超时,但仅在开始监视目录之前睡觉。

因此,代码看起来像:

try {
            WatchService watchService = FileSystems.getDefault().newWatchService();
            Paths.get(dirPath).register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
            WatchKey key;
            while ((key = watchService.take()) != null) {
                for (WatchEvent<?> event : key.pollEvents()) {
                    String fileName = event.context().toString();
                    if (isPdfFile(fileName)) {
                        consumer.accept(dirPath + fileName);
                        return;
                    }
                }
                key.reset();
            }
        }
        catch (IOException | InterruptedException e) {} 

或其他解决方法?

如果您在等待事件时想要超时,则需要使用WatchService.poll(long,TimeUnit)。如果我正确理解您的问题,您想等待最多两分钟,在第一个匹配活动中短路。在这种情况下,您需要跟踪您实际等待的时间和剩余持续时间的时间。否则,您将在第一个非匹配事件中等待每个循环或更糟糕的情况,或者更糟。我相信以下(未经测试的)代码应与您想要的相似:

public static Optional<Path> watch(Path directory, Predicate<? super Path> filter)
        throws IOException {
    try (WatchService service = directory.getFileSystem().newWatchService()) {
        directory.register(service, StandardWatchEventKinds.ENTRY_CREATE);
        long timeout = TimeUnit.NANOSECONDS.convert(2L, TimeUnit.MINUTES);
        while (timeout > 0L) {
            final long start = System.nanoTime();
            WatchKey key = service.poll(timeout, TimeUnit.NANOSECONDS);
            if (key != null) {
                for (WatchEvent<?> event : key.pollEvents()) {
                    Path context = (Path) event.context();
                    if (filter.test(context)) {
                        return Optional.of(directory.resolve(context));
                    }
                }
                key.reset();
                // Accounts for the above execution time. If you don't want that you
                // can move this to before the "for" loop.
                timeout -= System.nanoTime() - start;
            } else {
                break;
            }
        }
    } catch (InterruptedException ignore) {}
    return Optional.empty();
} 

使用try-with-with-Resources完成后,此代码也关闭WatchService。它还返回Optional而不是使用ConsumerPredicate将与isPdfFile(...)做同样的事情。我这样做是因为它使该方法独立(这对一个示例来说是有益的),但是如果需要,您可以继续使用isPdfFileConsumer。使用该方法可能看起来像:

Path dir = ...;
watch(dir, file -> isPdfFile(file)).ifPresent(/* do something */);

顺便说一句,您的代码使用take()并检查它是否返回null。该方法切勿返回null,因为它需要等到事件可用。换句话说,它返回WatchKey或投掷。

相关内容

最新更新