FileSystemWatcher监控FTP上传文件失效问题求助
问题分析与解决方案
核心问题原因
Windows Server 2012与2008 R2的FileSystemWatcher底层文件通知机制存在差异,再加上多数FTP服务器的上传逻辑(先创建临时文件,上传完成后重命名为目标CSV文件),导致仅监听Created和Changed事件无法捕获FTP上传的文件。
具体解决步骤
1. 添加Renamed事件监听
FTP上传时通常会生成临时文件(如带.tmp/.part后缀),完成上传后才重命名为.csv,这种操作只会触发Renamed事件。修改你的OnStart代码,新增该事件监听:
AddHandler ZMES_FileWatcher.Renamed, AddressOf OnFileRenamed
同时新增对应的事件处理子程序:
Private Sub OnFileRenamed(sender As Object, e As RenamedEventArgs) ' 校验重命名后的文件是否为目标CSV格式 If IO.Path.GetExtension(e.FullPath).Equals(".csv", StringComparison.OrdinalIgnoreCase) Then WriteToLog($"检测到重命名的CSV文件: {e.OldFullPath} -> {e.FullPath}") ' 复用原有OnNewFile的处理逻辑 OnNewFile(sender, New FileSystemEventArgs(WatcherChangeTypes.Created, IO.Path.GetDirectoryName(e.FullPath), IO.Path.GetFileName(e.FullPath))) End If End Sub
2. 精简NotifyFilter参数
当前配置的NotifyFilter包含过多非必要属性,可能干扰关键事件捕获。调整为仅监听与文件创建、修改相关的通知:
ZMES_FileWatcher.NotifyFilter = NotifyFilters.FileName Or NotifyFilters.LastWrite
3. 检查服务运行权限
Windows Server 2012权限管控更严格,需确保服务运行账号对监控目录拥有完全控制权限(含读取、写入、修改、删除等),避免因FTP上传文件的权限继承问题导致事件通知被拦截。
4. 处理文件锁定问题
FTP上传过程中文件会处于锁定状态,即使触发事件也无法正常处理。在OnNewFile中添加锁定检测逻辑:
Private Sub OnNewFile(sender As Object, e As FileSystemEventArgs) Dim retryCount As Integer = 5 Dim fileLocked As Boolean = True ' 重试等待文件解锁 While retryCount > 0 AndAlso fileLocked Try Using fs As New IO.FileStream(e.FullPath, IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.None) fileLocked = False End Using Catch ex As IO.IOException retryCount -= 1 Threading.Thread.Sleep(1000) End Try End If If Not fileLocked Then WriteToLog($"检测到新文件: {e.FullPath}") ' 执行后续业务逻辑 Else WriteToLog($"文件{e.FullPath}多次重试仍锁定,跳过处理") End If End Sub
5. 验证FTP服务器配置
检查FTP服务器是否直接创建目标CSV文件,还是通过临时文件重命名完成上传。若为后者,确认服务器未禁用文件系统通知(部分FTP服务器会禁用该功能以提升性能)。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

