Java catch linux 挂载/卸载一个文件夹
Java catch linux mount / unmount for a folder
我有一个 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();
}
}
});
}
运行 方法(实现为可运行):
/**
* 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 最终导致线程终止。
从那时起,我真的不知道什么时候会再次挂载该文件夹 - 重新 运行 监视器线程。
监控文件夹装载/卸载的最佳方法是什么?
请注意:被监视的端点文件夹不一定是挂载点,它(挂载的文件夹)可能是它的祖先之一。
如有任何帮助,我们将不胜感激!
您可以查看 /proc/mounts
文件以查看挂载是否仍然存在。
不确定 OpenSUSE,但我认为它们的工作方式与 Redhat 风格相同 linux。
https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-proc-mounts.html
按照@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
我有一个 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();
}
}
});
}
运行 方法(实现为可运行):
/**
* 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 最终导致线程终止。
从那时起,我真的不知道什么时候会再次挂载该文件夹 - 重新 运行 监视器线程。
监控文件夹装载/卸载的最佳方法是什么?
请注意:被监视的端点文件夹不一定是挂载点,它(挂载的文件夹)可能是它的祖先之一。
如有任何帮助,我们将不胜感激!
您可以查看 /proc/mounts
文件以查看挂载是否仍然存在。
不确定 OpenSUSE,但我认为它们的工作方式与 Redhat 风格相同 linux。 https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-proc-mounts.html
按照@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