【问题标题】:Java catch linux mount / unmount for a folderJava 捕获 linux 挂载/卸载文件夹
【发布时间】:2017-12-15 13:12:25
【问题描述】:

我有一个 java 项目,其中一个组件是监视安装到我机器上的特定文件夹。
我的 linux 版本是 OpenSUSE 42.1

为了监视我使用 java 的 Watch Service 的文件夹。
附上我们在网上找到的文件夹监控的主要代码,根据需要修改。
(抱歉没有版权,找不到出处)。
构造函数:

/**
 * Creates a WatchService and registers the given directory
 */
public WatchDir(Path dir, Kind<?>... dirWatchKinds) throws IOException {
    this.watcher = FileSystems.getDefault().newWatchService();
    this.keys = new HashMap<WatchKey,Path>();

    register(dir, dirWatchKinds);
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            try {
                watcher.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
}

Run方法(实现为runnable):

/**
 * Process all events for keys queued to the watcher
 */
public void run() {
    while (shouldRun) {

        // wait for key to be signalled
        WatchKey key;
        try {               
            key = watcher.take();
        } catch (Exception x) {             
            return;
        }

        Path dir = keys.get(key);
        if (dir == null) {
            log.error("WatchKey not recognized!!");
            continue;
        }

        for (WatchEvent<?> event: key.pollEvents()) {
            WatchEvent.Kind<?> kind = event.kind();

            if (kind == OVERFLOW) {
                continue;
            }

            // Context for directory entry event is the file name of entry
            WatchEvent<Path> ev = cast(event);
            Path name = ev.context();
            Path child = dir.resolve(name);

           handleDirEvent(child, ev.kind());

        }

        // reset key and remove from set if directory no longer accessible
        boolean valid = key.reset();
        if (!valid) {
            // Check that dir path still exists. If not, notify user and whoever run the thread
            if (Files.notExists(dir)){
                //log.error(String.format("Directory ", arg1));
                fireFileChangedEvent(dir.getFileName().toString(), FileState.Deleted);
            }

            keys.remove(key);

            // all directories are inaccessible
            if (keys.isEmpty()) {
                break;
            }
        }
    }
}

现在解决我的问题。
安装的文件夹容易断开连接,这可能会在我的程序范围之外处理(我猜是从终端)。
目前,当它发生时,watcher.take() 正在收到通知,没有任何事件需要处理,
boolean valid = key.reset() 上,它的值为 false,最终导致线程终止。
从那时起,我真的不知道何时会再次安装该文件夹 - 用于重新运行监视器线程。

监控文件夹挂载/卸载的最佳方法是什么?
请注意:被监控的端点文件夹不一定是挂载点,它(挂载的文件夹)可能是一个它的祖先。

任何帮助将不胜感激!

【问题讨论】:

    标签: java mount opensuse watchservice


    【解决方案1】:

    您可以查看/proc/mounts 文件以查看挂载是否仍然存在。

    不确定 OpenSUSE,但我认为它们的工作方式与 Redhat 风格的 linux 相同。 https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-proc-mounts.html

    【讨论】:

    • 感谢您的回答,有没有办法监控这个文件?还是我需要在每个时间间隔进行深入研究?
    • inotify 用这样的东西:github.com/glassbeam/watcher 我自己没有用过这个,所以不能真正帮助你
    【解决方案2】:

    在@StefanE 回答之后,我找到了以下使用 java native 读取此文件的好示例。
    取自this answer,
    它很好地解析了/etc/mtab 文件,在我的具体用法中,我会在每个时间间隔检查这个文件,看看文件夹是否再次挂载。

        mntent mntEnt;
        Pointer stream = CLib.INSTANCE.setmntent("/etc/mtab", "r");
        while ((mntEnt = CLib.INSTANCE.getmntent(stream)) != null) {
            if (mntEnt.mnt_type.equalsIgnoreCase("cifs")){
                System.out.println("Mounted from: " + mntEnt.mnt_fsname);
                System.out.println("Mounted on: " + mntEnt.mnt_dir);
                System.out.println("File system type: " + mntEnt.mnt_type);
                System.out.println("-------------------------------");  
            }
        }
    
        CLib.INSTANCE.endmntent(stream);
    

    对于我的具体用法,结果是

    Mounted from: //192.168.163.129/storage1/rawData
    Mounted on: /mntMS/StorageServer1/rawData
    File system type: cifs
    
    Mounted from: //192.168.163.129/storage2/output
    Mounted on: /mntMS/StorageServer2/output
    File system type: cifs
    
    Mounted from: //192.168.163.129/storage2/rawData
    Mounted on: /mntMS/StorageServer2/rawData
    File system type: cifs
    
    Mounted from: //127.0.0.1/storage1/output
    Mounted on: /mntMS/StorageServer1/output
    File system type: cifs
    

    【讨论】:

    • 您好,很高兴能为您提供帮助。不要忘记接受答案! :)
    猜你喜欢
    • 2012-04-18
    • 1970-01-01
    • 2023-03-08
    • 2017-11-19
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    相关资源
    最近更新 更多