您的位置 首页 java

Java NIO:轮询架构上的事件驱动架构

文件传输允许本地文件系统中的文件被读取和写入。轮询传输以给定的时间间隔重复扫描目录或目录集。这通常是一个开销,导致系统资源的低效使用,因为即使没有修改也会周期性地扫描整个集或目录和文件。作为解决方案,NIO文件传输作为非轮询传输,当且仅当在其监视范围内创建或修改文件或目录时,才会触发事件。

这是如何工作的

JDK 7提供了一个名为 java .nio 的特殊包。Java NIO(新I / O)是用于Java(来自Java 1.4)的替代I / O API,用作标准Java I / O和Java网络API的替代品。Java NIO提供了与标准I / O API不同的工作方式。该包提供了一个包java.nio. file 的子包 ,该文件包含名为 WatchService API 的文件系统更改通知 API。该API可以使用手表服务注册一个目录(或一组目录),该服务在启动时捕获创建或修改文件和目录的所有事件,并通过类似于Linux inotify API的事件队列使其可用。

Path dir = Paths.get(“/ tmp”);WatchService观察者= FileSystems.getDefault()。newWatchService();WatchKey key = dir.register(watcher,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY); 

所以,在这个基于事件的文件传输中,我们给出一组参数如下:

  • 根路径:文件/目录的根路径来查看文件。

  • 路径模式:用于监视文件的文件路径模式。

  • 模式语法:文件路径模式(glob或regex)的模式语法。

最初,当watch服务启动时,它将注册我们注册watch服务的根目录下的所有目录和子目录。然后它会注意根目录下注册的每个目录。无论何时创建,修改或删除文件或目录,都会触发事件。但事件是根据我们感兴趣的注册事件触发的,所以如果是一个目录,它会注册在watch-service中,以便检测它的内部变化,如果是一个文件,那么被采取的过程。

触发的事件由watch服务添加到队列中,我们必须通过将它们作为批次由key.pollEvents()处理。该返回的事件有4种类型的 StandardWatchEventKinds ,如下所示:

  • ENTRY_CREATE:创建目录条目。

  • ENTRY_DELETE: 目录条目被删除。

  • ENTRY_MODIFY: 修改目录条目。

  • 溢出: 表示事件可能已丢失或丢弃。

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

路径模式和模式语法用于过滤我们想要的文件。我们可以在glob或regex的语法中给出一个路径模式,并要求扫描几个目录,找到我们想要的几种类型的文件。

如果在从文件中获取事件后给出这些类型的模式,我们使用路径模式检查文件名+文件路径。所以我们使用java.nio.FileSystem包提供的getPathMatcher方法。我们创建一个自定义 GRPattern 类,它使用模式语法和路径模式保留模式细节。

public boolean isMatchPattern(GRPattern GRPattern,Path file){
 PathMatcher matcher = FileSystems.getDefault()。getPathMatcher(GRPattern.getPatternSyntax()+
 。Paths.get(GRPattern.getPathPattern())的toString());
 路径名= 文件 .getFileName(); 返回名称!= null && matcher.matches(file);} 

OVERFLOW活动

OVERFLOW是一种特殊类型的事件。我们不必注册OVERFLOW事件来接收它。当接收到这种类型的事件时,这意味着队列溢出,并且没有空间来添加当前创建的事件。在我们重置队列之后,它再次启动进程,但由于这个溢出可能会有一个或多个事件丢失。所以,应该手动处理如下:

  1. 当检测到OVERFLOW事件时,我们可以使用系统时间和目录。然后,我们可以扫描相关目录,找出在此之前创建的文件。这不是一个开销,因为正常的过程检测到在该目录中创建的文件,所以有很少的文件要处理。但是如果我们不从系统中删除检测到的文件,这种方法将无法正常工作。

  2. 我们可以停止扫描涉及溢出的当前目录。然后,我们可以将该目录注册为创建的新目录,并从头开始(仅针对该目录)启动该过程。

OVERFLOW事件的示例

假设我们有一个新的目录注册到手表服务的情况,并且在那个时候,大量的文件(例如10,000)被复制到该目录或在该目录内部创建。然后,监视服务将检测所有文件并排队处理。但是,如果文件的出队处理部分比将文件排入队列慢,则会抛出事件OVERFLOW。

高级

有一种特殊类型的情况,我们将会错过一些文件。如果文件系统以高速率创建文件或目录,则在我们在手表服务中注册该目录之前,可能会在特定目录中创建一些文件数量,尽管它不需要相当长的时间。所以在这种情况下,还要手动处理如下:

当目录注册到手表服务时,我们知道受影响的目录。然后,我们可以扫描相关目录中已创建的文件。那些是由于观察服务注册该特定目录所花费的时间而遗漏的文件。观看服务注册后创建的文件将被正常情况所捕获。

对于特定目录的扫描,我们可以使用java.nio.file包提供的 FileVisitor 接口 。该界面有四种方法对应于这些情况:

  • PreVisitDirectory:在访问目录的条目之前调用。

  • PostVisitDirectory:访问目录中的所有条目后调用。

  • VisitFile:在正在访问的文件上调用。

  • VisitFileFailed:当文件无法访问时调用。

所以,通过这个层次的实现,我们可以检测到在本地文件系统中创建的任何文件,而不需要轮询并满足用户的要求。

1、具有1-5工作经验的,面对目前流行的技术不知从何下手,

需要突破技术瓶颈的。2、在公司待久了,过得很安逸,

但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的。

3、如果没有工作经验,但基础非常扎实,对java工作机制,

常用设计思想,常用java开发框架掌握熟练的。

4、觉得自己很牛B,一般需求都能搞定。

但是所学的知识点没有系统化,很难在技术领域继续突破的。

5. 群号:高级架构群 606187239备注好信息!

6.阿里Java高级大牛直播讲解知识点,分享知识,

多年工作经验的梳理和总结,带着大家全面、

科学地建立自己的技术体系和技术认知!

文章来源:智云一二三科技

文章标题:Java NIO:轮询架构上的事件驱动架构

文章地址:https://www.zhihuclub.com/178817.shtml

关于作者: 智云科技

热门文章

网站地图