FileSystemWatcher事件多次触发的解决方法 (C++版)
2017-09-14 11:50
573 查看
FileSystemWatcher
这篇文章是承接上一篇文章发布的,主要是解决使用FileSystemWatcher类时出现的多次检测到相同文件,还有FTP下载产物中间文件TMP的鉴别
1.使用时间戳
PS:C#的代码是这么写的:using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
namespace FileSystem
{
public delegate void FileSystemEvent(String path);
public interface IDirectoryMonitor
{
event FileSystemEvent Change;
void Start();
}
public class DirectoryMonitor : IDirectoryMonitor
{
private readonly FileSystemWatcher m_fileSystemWatcher =
new FileSystemWatcher();
private readonly Dictionary<string, DateTime> m_pendingEvents =
new Dictionary<string, DateTime>();
private readonly Timer m_timer;
private bool m_timerStarted = false;
public DirectoryMonitor(string dirPath)
{
m_fileSystemWatcher.Path = dirPath;
m_fileSystemWatcher.IncludeSubdirectories = false;
m_fileSystemWatcher.Created += new FileSystemEventHandler(OnChange);
m_fileSystemWatcher.Changed += new FileSystemEventHandler(OnChange);
m_timer = new Timer(OnTimeout, null, Timeout.Infinite, Timeout.Infinite);
}
public event FileSystemEvent Change;
public void Start()
{
m_fileSystemWatcher.EnableRaisingEvents = true;
}
private void OnChange(object sender, FileSystemEventArgs e)
{
// Don't want other threads messing with the pending events right now
lock (m_pendingEvents)
{
// Save a timestamp for the most recent event for this path
m_pendingEvents[e.FullPath] = DateTime.Now;
// Start a timer if not already started
if (!m_timerStarted)
{
m_timer.Change(100, 100);
m_timerStarted = true;
}
}
}
private void OnTimeout(object state)
{
List<string> paths;
// Don't want other threads messing with the pending events right now
lock (m_pendingEvents)
{
// Get a list of all paths that should have events thrown
paths = FindReadyPaths(m_pendingEvents);
// Remove paths that are going to be used now
paths.ForEach(delegate(string path)
{
m_pendingEvents.Remove(path);
});
// Stop the timer if there are no more events pending
if (m_pendingEvents.Count == 0)
{
m_timer.Change(Timeout.Infinite, Timeout.Infinite);
m_timerStarted = false;
}
}
// Fire an event for each path that has changed
paths.ForEach(delegate(string path)
{
FireEvent(path);
});
}
private List<string> FindReadyPaths(Dictionary<string, DateTime> events)
{
List<string> results = new List<string>();
DateTime now = DateTime.Now;
foreach (KeyValuePair<string, DateTime> entry in events)
{
// If the path has not received a new event in the last 75ms
// an event for the path should be fired
double diff = now.Subtract(entry.Value).TotalMilliseconds;
if (diff >= 75)
{
results.Add(entry.Key);
}
}
return results;
}
private void FireEvent(string path)
{
FileSystemEvent evt = Change;
if (evt != null)
{
evt(path);
}
}
}
}
2.使用静态私有成员
using namespace msclr::interop;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Runtime::InteropServices;
ref class FSEventHandler
{
private:
static int count = 0;
static time_t startTime = 0;
static String ^ deforePath = "0";
void OnChanged(Object^ source, FileSystemEventArgs^ e)
{
char* path = (char*)(Marshal::StringToHGlobalAnsi(e->FullPath)).ToPointer();
String^Spath = marshal_as<String^>(path);
if (deforePath != Spath)
{
startS12(path);
deforePath = Spath;
}
}
public:
/*启动检测*/
int static run1(String ^ MonitorPath)
{
//创建一个FileSystemWatcher并设置它的属性.
FileSystemWatcher^ fsWatcher = gcnew FileSystemWatcher();
fsWatcher->Path = MonitorPath;
//设置缓冲区大小1M,根据需求设置
fsWatcher->InternalBufferSize = 1048576;
//监听文件、目录、文件大小的改变
fsWatcher->NotifyFilter = NotifyFilters::FileName | NotifyFilters::DirectoryName | NotifyFilters::Size;
//监听子目录
fsWatcher->IncludeSubdirectories = true;
//添加事件处理程序
FSEventHandler^ handler = gcnew FSEventHandler();
fsWatcher->Changed += gcnew FileSystemEventHandler(
handler, &FSEventHandler::OnChanged);
//开始监听
fsWatcher->EnableRaisingEvents = true;
system("pause");//把父进程阻塞起来,防止负责检测的子进程死掉
return 0;
}
};
我大致介绍一下我的想法:
就是利用一个中间的变量tempStringPath,来存放上一次检测到的路径,再触发事件后就是判断是否与上一次的路径是否相同,如果不相同才去执行下面的步骤。
但是局限性就是不能用在同名文件覆盖,或者同名文件修改的项目中。
相关文章推荐
- FileSystemWatcher事件多次触发的解决方法
- FileSystemWatcher事件多次触发的解决方法
- FileSystemWatcher事件多次触发的解决方法
- FileSystemWatcher事件多次触发解决办法
- c#的FileSystemWatcher对象监视文件的变化的事件,无休止的触发事件的解决办法
- 解决FileSystemWatcher事件多次触发的方法
- FileSystemWatcher 解决多次出发OnChanged事件
- FileSystemWatcher触发多次Change事件的解决办法 .
- FileSystemWatcher触发多次Change事件的解决办法
- 解决FileSystemWatcher事件多次触发的方法
- 解决FileSystemWatcher事件多次触发的方法
- FileSystemWatcher是软件程序开发常用到的一个监控组件,但是这个控件的Changed 时间方法老是触发2次或者多次,触发多次的情况
- FileSystemWatcher触发多次Change事件的解决办法
- FileSystemWatcher事件多次触发的解决方法
- C# 之 FileSystemWatcher事件多次触发的解决方法
- 解决FileSystemWatcher事件多次触发的方法
- FileSystemWatcher事件多次触发的解决方法
- FileSystemWatcher事件多次触发的解决方法
- js onmousewheel事件多次触发问题解决方法
- jquery mobile的触控点击事件会多次触发问题的解决方法