java nio改文件名字_使用java.nio在文件更改时引发创建/移动/删除事件

对于我想在文件系统中更改条目时更新条目的媒体库,我想通过使用this example尝试“新”java.nio file watching features.

我希望在创建,移动(重命名)或删除文件时获得有用的事件,但这是在windows7上观看文件夹时发生的事情(还没有尝试过其他操作系统):

格式:

[ThreadName] DEBUG 2012-04-09 18:20:35.934 GroupNumber-COMMAND:Path

ThreadName:每个监视文件夹都在其自己的线程中运行,该线程具有不同的ID

GroupNumber:使用相同GroupNumber发送的消息同时发送(通常为..)

命令:收到的命令

路径:收到的路径

Rename:

[Watch0] DEBUG 2012-04-09 18:20:35.934 2-ENTRY_DELETE: C:\tmp\tmp\test.avi

[Watch0] DEBUG 2012-04-09 18:20:35.935 2-ENTRY_CREATE: C:\tmp\tmp\test1.avi

[Watch0] DEBUG 2012-04-09 18:20:35.936 3-ENTRY_MODIFY: C:\tmp\tmp

[Watch0] DEBUG 2012-04-09 18:20:35.937 4-ENTRY_MODIFY: C:\tmp\tmp\test1.avi

[Watch4] DEBUG 2012-04-09 18:43:47.965 18-ENTRY_DELETE: F:\tmp\test.avi

[Watch4] DEBUG 2012-04-09 18:43:47.966 18-ENTRY_CREATE: F:\tmp\test1.avi

[Watch4] DEBUG 2012-04-09 18:43:47.967 19-ENTRY_MODIFY: F:\tmp\test1.avi

Create:

[Watch0] DEBUG 2012-04-09 18:22:02.055 5-ENTRY_CREATE: C:\tmp\test.avi

[Watch0] DEBUG 2012-04-09 18:22:02.066 6-ENTRY_MODIFY: C:\tmp\test.avi

[Watch0] DEBUG 2012-04-09 18:22:03.460 7-ENTRY_MODIFY: C:\tmp\test.avi

//Note the 1.4'' delay between the last two messages.

//This is the time required to actually copy the file

Move in same watch folder:

[Watch0] DEBUG 2012-04-09 18:18:42.395 0-ENTRY_DELETE: C:\tmp\test.avi

[Watch0] DEBUG 2012-04-09 18:18:42.396 0-ENTRY_MODIFY: C:\tmp\tmp

[Watch0] DEBUG 2012-04-09 18:18:42.396 1-ENTRY_CREATE: C:\tmp\tmp\test.avi

[Watch0] DEBUG 2012-04-09 18:18:42.396 1-ENTRY_MODIFY: C:\tmp\tmp\test.avi

Move to other watch folder on same drive:

[Watch1] DEBUG 2012-04-09 18:23:24.341 8-ENTRY_CREATE: C:\tmp2\test.avi

[Watch0] DEBUG 2012-04-09 18:23:24.341 8-ENTRY_DELETE: C:\tmp\test.avi

[Watch1] DEBUG 2012-04-09 18:23:24.342 10-ENTRY_MODIFY: C:\tmp2\test.avi

//The two 8 are lying. Both messages are being sent from different threads

//and the shared counter hasn't been incremented by any yet. The next entry has been

//incremented by two!

Move to other watch folder on different drive:

[Watch4] DEBUG 2012-04-09 18:25:42.324 11-ENTRY_CREATE: F:\tmp\test.avi

[Watch4] DEBUG 2012-04-09 18:25:42.338 12-ENTRY_MODIFY: F:\tmp\test.avi

[Watch4] DEBUG 2012-04-09 18:25:42.703 13-ENTRY_MODIFY: F:\tmp\test.avi

[Watch3] DEBUG 2012-04-09 18:25:49.433 14-ENTRY_DELETE: C:\tmp2\test.avi

//Note that the last delete message is being sent from another thread then the first ones.

//This is because the source and destination WatchDirs aren't the same

Delete:

[Watch9] DEBUG 2012-04-05 21:22:02.921 ENTRY_DELETE: C:\tmp\test (2011).mkv

有一组必须解释的“命令路径”,而不是单个事件.例如.删除由单个命令组成,而重命名和“在同一文件夹中移动”也以删除命令开始,但将由其将来的命令定义.另外,多个文件可以是例如并行移动,这将最终出现在属于不同操作的随机命令列表中,必须以某种方式对其进行排序.

我能想出的最好的是this class,其中事件在被接收时被排队,然后在另一个线程中被接收后检查片刻(1s)(如果正在生成其他事件并且属于相同的话,则给予一些时间)事件组’).

这在重命名,移动,创建或删除单个文件时有效,但如果开始并行复制多个文件或复制一批文件,则不再有任何工作.

我需要的任何实现是否已经存在(似乎是一个常见的用例)?或者有人知道如何处理这个问题以涵盖所有情况?

最后,它必须适用于Windows,Linux和osx.

一个更复杂的例子也应该得到支持

[Watch0] DEBUG 2012-04-09 19:10:17.774 0-ENTRY_CREATE: C:\tmp\tmp\testlarge.avi

[Watch0] DEBUG 2012-04-09 19:10:17.825 0-ENTRY_MODIFY: C:\tmp\tmp\testlarge.avi

[Watch0] DEBUG 2012-04-09 19:10:17.826 1-ENTRY_MODIFY: C:\tmp\tmp

[Watch0] DEBUG 2012-04-09 19:12:09.516 2-ENTRY_DELETE: C:\tmp\tmp\testsmall.avi

[Watch0] DEBUG 2012-04-09 19:12:09.516 3-ENTRY_CREATE: C:\tmp\testsmall.avi

[Watch0] DEBUG 2012-04-09 19:12:09.517 3-ENTRY_MODIFY: C:\tmp\testsmall.avi

[Watch0] DEBUG 2012-04-09 19:12:09.521 4-ENTRY_MODIFY: C:\tmp\tmp

[Watch0] DEBUG 2012-04-09 19:14:13.025 5-ENTRY_MODIFY: C:\tmp\tmp\testlarge.avi

这里,在创建大文件时正在移动一个小文件.

解决方法:

我看到的一件事是你为每个事件创建一个新的线程,你使用na lock对象来同步你的线程.

如果您创建ExecutorService,那就更好了

即重写您的代码,如:

private ExecutorService executorService;

private class WatchEventHandler implements Callable {

WatchEvent> event;

public WatchEventHandler(final WatchEvent> event) {

this.event = event;

}

@Override

public void call() throws Exception{

// do something with the event

// fireFileWatchAction();

}

}

public ManagedFolderWatcher(DOManagedFile managedFolder) throws IOException {

executorService = Executors.newFixedThreadPool(10);

...

}

并在您的运行/流程事件方法中

public void run() {

try {

while(true) {

WatchKey key = watcher.take();

....

for (WatchEvent> event : key.pollEvents()) {

...

// in my oppinon there is no need to delay the event

executorService.schedule(new WatchEventHandler(event));

}

...

}

} catch (InterruptedException ie) {

// todo: propper error handling

log.error("Thread interrupted", ie);

} catch (ClosedWatchServiceException cwse) {

// todo: propper error handling

log.error("WatchService allready closed.", cwse);

}

}

以这种方式实现它时,您甚至不需要锁定对象eventEntrySyncObj,并且您的Callable / Command具有触发fileWatchAction事件所需的所有信息.

标签:java,filesystems,watch,nio

来源: https://codeday.me/bug/20190609/1207889.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值