观看大量目录的最佳方法?

时间:2018-11-18 09:30:05

标签: java linux

我写了一个music player in Java/JavaFX,它(其中包括)监视用户的音乐库文件夹是否有任何更改,如果文件系统上有更改,则更新程序的库数据。

我用SimpleFileVisitorWatchService完成此操作。 SimpleFileVisitor递归地遍历目标文件夹层次结构,并向每个文件夹注册WatchService。完整代码如下。

在我的Ubuntu 18.04上,如果我尝试以这种方式注册许多文件夹,每个文件夹都有很多子文件夹,最终我会收到错误java.io.IOException: User limit of inotify watches reached

事实证明,Linux内核限制了文件/proc/sys/fs/inotify/max_user_watches中可以执行的inotify监视的数量。通用默认值为8192。此限制适用于用户运行的每个程序,还有其他使用率很高的流行程序,例如DropBox。

我的图书馆可能也有很多需求。对于可能使用该程序的用户来说,一个合理的估计是要查看1000-25000个文件夹。我希望大多数用户都落在2000-5000范围内。

一种解决方案是将错误通知用户,并告诉他们增加内核中的max_user_watches数,这是可以做到的,但是我不希望这样给用户增加负担避免。

是否还有另一种好方法可以在不重载Linux上的inotify编号的情况下通知Java中的文件夹层次结构更改?

我的完整观察者代码可以从第545行开始:https://github.com/JoshuaD84/HypnosMusicPlayer/blob/55da2819a3862d5c2a14797a9ce45e9171f7076e/src/net/joshuad/hypnos/Library.java#L545

您还可以在此处查看主要的沃克代码:

private void watcherRegisterAll ( final Path start ) {
    try {
        Files.walkFileTree( 
            start, 
            EnumSet.of( FileVisitOption.FOLLOW_LINKS ), 
            Integer.MAX_VALUE,
            new SimpleFileVisitor <Path>() {
                @Override
                public FileVisitResult preVisitDirectory ( Path dir, BasicFileAttributes attrs ) throws IOException {
                    WatchKey key = dir.register( 
                        watcher, 
                        StandardWatchEventKinds.ENTRY_CREATE, 
                        StandardWatchEventKinds.ENTRY_DELETE, 
                        StandardWatchEventKinds.ENTRY_MODIFY 
                    );

                    keys.put( key, dir );
                    return FileVisitResult.CONTINUE;
                }
            }
        );

    } catch ( IOException e ) {
        LOGGER.log( Level.INFO, "Unable to watch directory for changes: " + start.toString() );
    }
}

1 个答案:

答案 0 :(得分:1)

您的方法是正确的方法,而inotify是最有效的方法。如果遇到此问题,您可以提示用户代表他们增加限制,以提供更好的用户体验(您必须为此要求密码来执行特权升级)。