我通过文件系统观察器监视丢弃在ftp上的文件,然后移动到另一个目录.现在我触发了文件系统观察者的创建事件的副本,但显然在ftp的情况下,create只是一个存根文件,数据进入并填充文件,因为它上传到完成.任何人都有一个优雅的解决方案,或者我必须做我认为我必须做的事情
1 wait till last access time is about n ms in past before I copy 2 throw a control file in there to state that that file is done being copied,then delete control file 3 pound the crap out of it
解决方法
这是一个非常天真的实现,但它适合我的目的,我已经看到足够的人在网络上有这个问题所以决定贡献.考虑到我的问题的性质,实现对我的需求非常具体,我几乎完全不关心改变事件,但是如果他们需要做一些不同的事情,那么人们可以在那里抛出自己的代码,它实际上是创建的,导致最多的问题.我没有对此进行全面测试,但最初写它看起来不错
using System; using System.Collections.Generic; using System.IO; using System.Timers; namespace FolderSyncing { public class FTPFileSystemWatcher { private readonly string _path; public event FileSystemEventHandler FTPFileCreated; public event FileSystemEventHandler FTPFileDeleted; public event FileSystemEventHandler FTPFileChanged; private Dictionary<string,LastWriteTime> _createdFilestocheck; private readonly object _lockObject = new object(); private const int _milliSecondsSinceLastWrite = 5000; private const int _createdCheckTimerInterval = 2000; private readonly FileSystemWatcher _baseWatcher; public FTPFileSystemWatcher(string path,string Filter) { _path = path; _baseWatcher = new FileSystemWatcher(path,Filter); SetUpEventHandling(); } public FTPFileSystemWatcher(string path) { _path = path; _baseWatcher = new FileSystemWatcher(path); SetUpEventHandling(); } private void SetUpEventHandling() { _createdFilestocheck = new Dictionary<string,LastWriteTime>(); Timer copyTimer = new Timer(_createdCheckTimerInterval); copyTimer.Elapsed += copyTimer_Elapsed; copyTimer.Enabled = true; copyTimer.Start(); _baseWatcher.EnableRaisingEvents = true; _baseWatcher.Created += _baseWatcher_Created; _baseWatcher.Deleted += _baseWatcher_Deleted; _baseWatcher.Changed += _baseWatcher_Changed; } void copyTimer_Elapsed(object sender,ElapsedEventArgs e) { lock (_lockObject) { Console.WriteLine("Checking : " + DateTime.Now); DateTime datetocheck = DateTime.Now; List<string> toRemove = new List<string>(); foreach (KeyValuePair<string,LastWriteTime> fileToCopy in _createdFilestocheck) { FileInfo filetocheck = new FileInfo(_path + fileToCopy.Key); TimeSpan difference = filetocheck.LastWriteTime - fileToCopy.Value.Date; fileToCopy.Value.Update(fileToCopy.Value.Date.AddMilliseconds(difference.TotalMilliseconds)); if (fileToCopy.Value.Date.AddMilliseconds(_milliSecondsSinceLastWrite) < datetocheck) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.Created,_path,fileToCopy.Key); toRemove.Add(fileToCopy.Key); InvokeFTPFileCreated(args); } } foreach (string removal in toRemove) { _createdFilestocheck.Remove(removal); } } } void _baseWatcher_Changed(object sender,FileSystemEventArgs e) { InvokeFTPFileChanged(e); } void _baseWatcher_Deleted(object sender,FileSystemEventArgs e) { InvokeFTPFileDeleted(e); } void _baseWatcher_Created(object sender,FileSystemEventArgs e) { if (!_createdFilestocheck.ContainsKey(e.Name)) { FileInfo fileToCopy = new FileInfo(e.FullPath); _createdFilestocheck.Add(e.Name,new LastWriteTime(fileToCopy.LastWriteTime)); } } private void InvokeFTPFileChanged(FileSystemEventArgs e) { FileSystemEventHandler Handler = FTPFileChanged; if (Handler != null) { Handler(this,e); } } private void InvokeFTPFileDeleted(FileSystemEventArgs e) { FileSystemEventHandler Handler = FTPFileDeleted; if (Handler != null) { Handler(this,e); } } private void InvokeFTPFileCreated(FileSystemEventArgs e) { FileSystemEventHandler Handler = FTPFileCreated; if (Handler != null) { Handler(this,e); } } } public class LastWriteTime { private DateTime _date; public DateTime Date { get { return _date; } } public LastWriteTime(DateTime date) { _date = date; } public void Update(DateTime dateTime) { _date = dateTime; } } }