
使用spring实现文件系统的实时监控
概述
这篇文章出现的原因是为客户应用程序中需要添加一项新功能,使其可以随时处理复制到目录中的文件。监控目录是否变更是许多计算机系统和应用程序中的一项常见任务。在 Java 生态系统中,有不同的选项可用于执行此类任务。下面列出了几种可能的解决方案:
Java WatchService API:它是在 Java 7 中引入的一个比较低级的特性。Apache commons io:软件包监控器提供了一个用于监控文件系统事件的组件。Spring Integration's file support:这是 Spring 集成项目的一部分,该项目支持多种企业集成模式。Spring Boot 开发者工具中的 Filewatch 包:它允许监视本地文件系统的更改。
我们将选择第四种实现方式,因为它和spring集成,很容易实现。
用例
我们希望通过将 csv 文件复制到特定位置,在应用程序中创建新客户。文件完全传输后将被读取。然后,csv 文件将被验证、处理并移动到目标目录。以下是 csv 文件的示例:
csv 文件将始终包含标题行和按特定顺序排列的 5 列。
准备工作
该项目采用了以下技术:
Java 21Spring Boot 3.1.5Maven 3.9.1
您至少需要 java 17+、Spring Boot 3+ 和 Maven 3.8+ 来运行源代码。
依赖关系
必须将一种新的依赖项添加到 pom.xml 文件中才能导入必要的类。
这就是我们需要先准备好或者掌握的东西
监控目录
用于监视特定目录的文件更改的类是 FileSystemWatcher。它带有三个构造函数,但您很可能会使用接受三个参数的构造函数
让我们看一下每个参数
deamon:是否有一个守护线程监视变化。如果您希望在 jvm 停止时终止线程(监控),请将其设置为 true。pollInterval:再次检查更改之间等待的时间。QuietPeriod:确保检测到更改后等待的时间。如果您将大文件传输到该目录,则必须考虑这一点以避免文件损坏。
由于我们希望在不影响源代码的情况下更改上述所有参数值,因此将自定义属性添加到 application.properties 文件中
应用程序将每 5 分钟扫描一次目录是否有修改。如果更改将在 1 分钟后触发。这已经足够了,因为 csv 文件很小(小于 1 MB)。 相应的 Java 代码可以加载其中的值。
下一步是定义 bean 类型为 FileSystemWatch 的配置类
我们来回顾一下 fileSystemWatcher() 方法:
首先创建一个 fileSystemWatcher 实例,将 bean 属性中的值作为参数传递。bean 属性对象由 spring 容器管理并通过构造函数注入。调用 addSourceDirectory 方法。它需要一个代表要监视的目录的文件。addListener 方法采用文件更改事件的侦听器。FileChangeListener 是一个函数式接口,当文件发生更改时,将调用其方法 onChange。(可选)可以在 setTriggerFilter 方法中设置 FileFilter 以限制触发更改的文件。计算结果为布尔值的 lambda 表达式用于将文件限制为 csv。最后一个方法是 start 来启动监视源目录的更改。
请注意,有一个 predestroy 连接方法可以在 jvm 停止时正常关闭观察程序。
添加监听器
第二步是实现一个可以处理文件的 FileChangeListener。该接口也是函数式的,因此可以使用 lambda 表达式或方法引用。在我们的例子中,最好将它放在自己的类中,因为这样可以提高可读性。
正如前面提到的,当文件发生更改时,将调用 onChange 方法。参数 Set 是更改的文件的集合(自轮询间隔开始以来)。迭代完changeSet后,就可以通过getFiles方法从每个ChangedFiles对象中获取文件。因此,嵌套循环将用于访问各个文件。单个文件的类型为 ChangedFile,它提供对更改/事件的文件和类型的访问(这是一个具有三个值 ADD、DELETE 和 MODIFY 的枚举)。
回到代码,if 语句检查类型以确保仅处理 ADD 事件。其他将被忽略。CustomerCSVFileProcessor 类执行所有工作。
处理文件
处理文件的业务逻辑可以在 process 方法中找到(在 FileProcessor 接口中声明)。它需要 CustomerService 将 Customer 保存在数据库中,因此它是构造函数注入的。CustomerCSVFileProcessor 类被标记为组件,因为它也被注入到 Watcher 中。
该方法在 CSVParser 的帮助下解析 csv 文件。然后,每个 cvs 行(描述为 CSVRecord)都映射到客户实体并将其保存到数据库中。最后,foreach 循环完成,文件被移动到一个不同的位置。
测试应用程序
重新运行应用程序将从 CustomerFileWatcherConfig 配置类启动文件系统观察程序 bean。应用程序启动后,包含一些客户的 csv 文件就会复制到受监控的目录中。5 分钟后生成以下log
事实上,文件中的数据行已作为客户实体添加到数据库中,并且文件已成功移动。
总结
在这篇短文中,我们演示了如何配置 Spring 应用程序以监控本地目录。该功能在执行自动化任务时非常有用。例如,与其他服务结合使用,如 FTP 服务器将文件传输到目录,然后文件监视器将其拾取进行处理。最后 如果感觉有帮助的话 点个赞吧!