using FtpLib; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; namespace WindowsService1 { public partial class Service1 : ServiceBase { private int TimeoutMillis = 2000; //定时器触发间隔 private int _countFileChangeEvent = 0, _countTimerEvent = 0; System.IO.FileSystemWatcher fsw = new System.IO.FileSystemWatcher(); System.Threading.Timer m_timer = null; System.Threading.Timer m_timerDownLoad = null; List<String> files = new List<string>(); //记录待处理文件的队列 private Thread ThreadHello; private Thread ThreadDownLoad; private List<ChannelTvListInfo> lstNewTvInfo; public Service1() { InitializeComponent(); } //http://blog.csdn.net/hwt0101/article/details/8514291 //http://www.cnblogs.com/mywebname/articles/1244745.html //http://www.cnblogs.com/jzywh/archive/2008/07/23/filesystemwatcher.html /// <summary> /// 服务启动的操作 /// </summary> /// <param name="args"></param> protected override void OnStart(string[] args) { try { ThreadDownLoad = new Thread(new ThreadStart(ThreadTime)); ThreadDownLoad.Start(); ThreadHello = new Thread(new ThreadStart(Hello)); ThreadHello.Start(); WriteInLog("服务线程任务开始", false); System.Diagnostics.Trace.Write("线程任务开始"); } catch (Exception ex) { System.Diagnostics.Trace.Write(ex.Message); throw ex; } } public List<ChannelTvListInfo> listFTPFiles(string FTPAddress, string username, string password) { List<ChannelTvListInfo> listinfo = new List<ChannelTvListInfo>(); using (FtpConnection ftp = new FtpConnection(FTPAddress, username, password)) { ftp.Open(); ftp.Login(); foreach (var file in ftp.GetFiles("/")) { listinfo.Add(new ChannelTvListInfo { TVName = file.Name, LastWriteTime = Convert.ToDateTime(file.LastWriteTime).ToString("yyyy/MM/dd HH:mm") }); } ftp.Dispose(); ftp.Close(); } return listinfo; } /// <summary> /// 服务停止的操作 /// </summary> protected override void OnStop() { try { ThreadHello.Abort(); WriteInLog("服务线程停止", false); System.Diagnostics.Trace.Write("线程停止"); } catch (Exception ex) { System.Diagnostics.Trace.Write(ex.Message); } } private void Hello() { try { fsw.Filter = "*.xml"; //设置监控文件的类型 fsw.Path = @"D:ChannelTvXML"; //设置监控的文件目录 fsw.IncludeSubdirectories = true; //设置监控C盘目录下的所有子目录 fsw.InternalBufferSize = 100000; fsw.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; ; //设置文件的文件名、目录名及文件的大小改动会触发Changed事件 fsw.Changed += new FileSystemEventHandler(this.fsw_Changed); fsw.Error += new ErrorEventHandler(this.fsw_Error); fsw.EnableRaisingEvents = true; // Create the timer that will be used to deliver events. Set as disabled if (m_timer == null) { //设置定时器的回调函数。此时定时器未启动 m_timer = new System.Threading.Timer(new TimerCallback(OnWatchedFileChange), null, Timeout.Infinite, Timeout.Infinite); } } catch (Exception ex) { System.Diagnostics.Trace.Write(ex.Message); throw ex; } Thread.Sleep(5000); } private void ThreadTime() { List<ChannelTvListInfo> lstNewTvInfo = listFTPFiles("60.208.140.170", "", ""); WriteInLog(lstNewTvInfo.Count + "获取列表信息成功", false); // Create the timer that will be used to deliver events. Set as disabled if (m_timerDownLoad == null) { //设置定时器的回调函数。此时定时器未启动 m_timerDownLoad = new System.Threading.Timer(new TimerCallback(DownLoadTvListInfo), null, Timeout.Infinite, Timeout.Infinite); } Thread.Sleep(5000); } private void DownLoadTvListInfo(object state) { List<ChannelTvListInfo> lstOldTvInfo = new List<ChannelTvListInfo>(); DirectoryInfo TheFolder = new DirectoryInfo(@"D:ChannelTvXML"); foreach (FileInfo NextFile in TheFolder.GetFileSystemInfos()) { lstOldTvInfo.Add(new ChannelTvListInfo { TVName = NextFile.Name, LastWriteTime = NextFile.LastWriteTime.ToString("yyyy/MM/dd HH:mm") }); } var result = lstNewTvInfo.Except(lstOldTvInfo, new ProductComparer()).ToList(); if (result.Count > 0) { foreach (var item in result) { new FtpHelper().DownloadFtpFile("", "", "60.208.140.170", @"D:ChannelTvXML", item.TVName); WriteInLog(item.TVName + "下载成功", false); } } } private void fsw_Changed(object sender, FileSystemEventArgs e) { Mutex mutex = new Mutex(false, "Wait"); mutex.WaitOne(); if (!files.Contains(e.Name)) { files.Add(e.Name); } mutex.ReleaseMutex(); //重新设置定时器的触发间隔,并且仅仅触发一次 m_timer.Change(TimeoutMillis, Timeout.Infinite); } /// <summary> /// 定时器事件触发代码:进行文件的实际处理 /// </summary> /// <param name="state"></param> private void OnWatchedFileChange(object state) { _countTimerEvent++; WriteInLog(string.Format("TimerEvent {0}", _countTimerEvent.ToString("#00")), false); List<String> backup = new List<string>(); Mutex mutex = new Mutex(false, "Wait"); mutex.WaitOne(); backup.AddRange(files); files.Clear(); mutex.ReleaseMutex(); foreach (string file in backup) { _countFileChangeEvent++; WriteInLog(string.Format("FileEvent {0} :{1}文件已于{2}进行{3}", _countFileChangeEvent.ToString("#00"), file, DateTime.Now, "changed"), false); } } private void fsw_Error(object sender, ErrorEventArgs e) { WriteInLog(e.GetException().Message, false); } /// <summary> /// 写入文件操作 /// </summary> /// <param name="msg">写入内容</param> /// <param name="IsAutoDelete">是否删除</param> private void WriteInLog(string msg, bool IsAutoDelete) { try { string logFileName = @"D:DownTvList_" + DateTime.Now.ToString("yyyyMMdd") + "_log.txt" + ""; // 文件路径 FileInfo fileinfo = new FileInfo(logFileName); if (IsAutoDelete) { if (fileinfo.Exists && fileinfo.Length >= 1024) { fileinfo.Delete(); } } using (FileStream fs = fileinfo.OpenWrite()) { StreamWriter sw = new StreamWriter(fs); sw.BaseStream.Seek(0, SeekOrigin.End); sw.Write("INFO-" + DateTime.Now.ToString() + "--日志内容为:" + msg + " "); //sw.WriteLine("====================================="); sw.Flush(); sw.Close(); } } catch (Exception ex) { ex.ToString(); } } } }
FtpHelper.cs 类代码 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace WindowsService1 { public class FtpHelper { private FtpWebRequest ftpRequest = null; private FtpWebResponse ftpResponse = null; private Stream ftpStream = null; /// <summary> /// Get Filelist Name /// </summary> /// <param name="userId">ftp userid</param> /// <param name="pwd">ftp password</param> /// <param name="ftpIP">ftp ip</param> /// <returns></returns> public string[] GetFtpFileName(string userId, string pwd, string ftpIP, string filename) { string[] downloadFiles; StringBuilder result = new StringBuilder(); try { ftpRequest = (FtpWebRequest)FtpWebRequest.Create(ftpIP + "/" + filename); ftpRequest.Credentials = new NetworkCredential(userId, pwd); ftpRequest.UseBinary = true; ftpRequest.UsePassive = true; ftpRequest.KeepAlive = true; ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory; ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); ftpStream = ftpResponse.GetResponseStream(); StreamReader ftpReader = new StreamReader(ftpStream); string line = ftpReader.ReadLine(); while (line != null) { result.Append(line); result.Append(" "); line = ftpReader.ReadLine(); } result.Remove(result.ToString().LastIndexOf(' '), 1); ftpReader.Close(); ftpStream.Close(); ftpResponse.Close(); ftpRequest = null; return result.ToString().Split(' '); } catch (Exception ex) { downloadFiles = null; return downloadFiles; } } public string[] GetFtpFileName(string userId, string pwd, string ftpIP) { string[] downloadFiles; StringBuilder result = new StringBuilder(); try { ftpRequest = (FtpWebRequest)FtpWebRequest.Create(ftpIP + "/"); ftpRequest.Credentials = new NetworkCredential(userId, pwd); ftpRequest.UseBinary = true; ftpRequest.UsePassive = true; ftpRequest.KeepAlive = true; ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory; ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); ftpStream = ftpResponse.GetResponseStream(); StreamReader ftpReader = new StreamReader(ftpStream); string line = ftpReader.ReadLine(); while (line != null) { result.Append(line); result.Append(" "); line = ftpReader.ReadLine(); } result.Remove(result.ToString().LastIndexOf(' '), 1); ftpReader.Close(); ftpStream.Close(); ftpResponse.Close(); ftpRequest = null; return result.ToString().Split(' '); } catch (Exception ex) { downloadFiles = null; return downloadFiles; } } /// <summary> ///从ftp服务器上下载文件的功能 /// </summary> /// <param name="userId"></param> /// <param name="pwd"></param> /// <param name="ftpUrl">ftp地址</param> /// <param name="filePath"></param> /// <param name="fileName"></param> public void DownloadFtpFile(string userId, string pwd, string ftpUrl, string filePath, string fileName) { FtpWebRequest reqFTP = null; FtpWebResponse response = null; try { String onlyFileName = Path.GetFileName(fileName); string downFileName = filePath + "\" + onlyFileName; string url = "ftp://" + ftpUrl + "/" + fileName; if (File.Exists(downFileName)) { DeleteDir(downFileName); } FileStream outputStream = new FileStream(downFileName, FileMode.Create); reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(url)); reqFTP.Credentials = new NetworkCredential(userId, pwd); reqFTP.UseBinary = true; reqFTP.UsePassive = true; reqFTP.KeepAlive = true; reqFTP.Method = WebRequestMethods.Ftp.DownloadFile; response = (FtpWebResponse)reqFTP.GetResponse(); Stream ftpStream = response.GetResponseStream(); long cl = response.ContentLength; int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; readCount = ftpStream.Read(buffer, 0, bufferSize); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } ftpStream.Close(); outputStream.Close(); response.Close(); } catch (Exception ex) { throw ex; } } /// 基姆拉尔森计算公式计算日期 /// </summary> /// <param name="y">年</param> /// <param name="m">月</param> /// <param name="d">日</param> /// <returns>星期几</returns> public static string CaculateWeekDay(int y, int m, int d) { if (m == 1 || m == 2) { m += 12; y--; //把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。 } int week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; string weekstr = ""; switch (week) { case 0: weekstr = "星期一"; break; case 1: weekstr = "星期二"; break; case 2: weekstr = "星期三"; break; case 3: weekstr = "星期四"; break; case 4: weekstr = "星期五"; break; case 5: weekstr = "星期六"; break; case 6: weekstr = "星期日"; break; } return weekstr; } /// <summary> /// 返回不带后缀的文件名 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public static string GetFirstFileName(string fileName) { return Path.GetFileNameWithoutExtension(fileName); } #region 删除指定目录以及该目录下所有文件 /// </summary><param name="dir">欲删除文件或者目录的路径</param> public static void DeleteDir(string dir) { CleanFiles(dir);//第一次删除文件 CleanFiles(dir);//第二次删除目录 } /// <summary> /// 删除文件和目录 /// </summary> ///使用方法Directory.Delete( path, true) private static void CleanFiles(string dir) { if (!Directory.Exists(dir)) { File.Delete(dir); return; } else { string[] dirs = Directory.GetDirectories(dir); string[] files = Directory.GetFiles(dir); if (0 != dirs.Length) { foreach (string subDir in dirs) { if (null == Directory.GetFiles(subDir)) { Directory.Delete(subDir); return; } else CleanFiles(subDir); } } if (0 != files.Length) { foreach (string file in files) { File.Delete(file); } } else Directory.Delete(dir); } } #endregion } public class ChannelListInfo { // public string ChannelID { get; set; } public string WeekDate { get; set; } public string ChannelTV { get; set; } public string ChannelName { get; set; } public string ChannelType { get; set; } public string ChannelSummary { get; set; } // public string ChannelImg { get; set; } public DateTime ChannelStartDate { get; set; } public DateTime ChannelEndDate { get; set; } // public DateTime? AddTime { get; set; } public DateTime? ChannelPlayDate { get; set; } } public class ChannelTvListInfo { public string TVName { get; set; } public string LastWriteTime { get; set; } } // Custom comparer for the Product class public class ProductComparer : IEqualityComparer<ChannelTvListInfo> { // Products are equal if their names and product numbers are equal. public bool Equals(ChannelTvListInfo x, ChannelTvListInfo y) { //Check whether the compared objects reference the same data. if (Object.ReferenceEquals(x, y)) return true; //Check whether any of the compared objects is null. if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; //Check whether the products' properties are equal. return x.TVName == y.TVName && x.LastWriteTime == y.LastWriteTime; } // If Equals() returns true for a pair of objects // then GetHashCode() must return the same value for these objects. public int GetHashCode(ChannelTvListInfo product) { //Check whether the object is null if (Object.ReferenceEquals(product, null)) return 0; //Get hash code for the Name field if it is not null. int hashProductName = product.TVName == null ? 0 : product.TVName.GetHashCode(); //Get hash code for the Code field. int hashProductCode = product.LastWriteTime.GetHashCode(); //Calculate the hash code for the product. return hashProductName ^ hashProductCode; } } }