C#開發(fā)windows服務(wù)實(shí)現(xiàn)自動(dòng)從FTP服務(wù)器下載文件
最近在做一個(gè)每天定點(diǎn)從FTP自動(dòng)下載節(jié)目.xml并更新到數(shù)據(jù)庫(kù)的功能。首先想到用 FileSystemWatcher來(lái)監(jiān)控下載到某個(gè)目錄中的文件是否發(fā)生改變,如果改變就執(zhí)行相應(yīng)的操作,然后用timer來(lái)設(shè)置隔多長(zhǎng)時(shí)間來(lái)下載。后來(lái)又想想,用windwos服務(wù)來(lái)實(shí)現(xiàn)。
效果圖:

執(zhí)行的Log日志:
INFO-2016/5/24 0:30:07--日志內(nèi)容為:0/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 1:30:07--日志內(nèi)容為:1/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 2:30:07--日志內(nèi)容為:2/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 3:30:07--日志內(nèi)容為:3/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 4:30:07--日志內(nèi)容為:4/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 5:30:07--日志內(nèi)容為:5/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 6:30:07--日志內(nèi)容為:6/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 7:30:07--日志內(nèi)容為:7/30/7進(jìn)行time觸發(fā) INFO-2016/5/24 7:30:07--日志內(nèi)容為:TimerEvent 01 INFO-2016/5/24 7:30:07--日志內(nèi)容為:TimerEvent 01 :共獲取77個(gè)節(jié)目列表信息成功。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:服務(wù)器與本地節(jié)目列表信息進(jìn)行對(duì)比開始。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:得到要更新的節(jié)目列表共77個(gè) INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 01 :BTV-1(高清).xml文件重新下載開始。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 01 :BTV-1(高清).xml文件內(nèi)容已于2016/05/24 00:01進(jìn)行changed并重新下載成功。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 01 :BTV-1(高清).xml文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步開始。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 01 :BTV-1(高清).xml文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步成功。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 02 :CCTV-1(高清).xml文件重新下載開始。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 02 :CCTV-1(高清).xml文件內(nèi)容已于2016/05/24 00:01進(jìn)行changed并重新下載成功。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 02 :CCTV-1(高清).xml文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步開始。 INFO-2016/5/24 7:31:08--日志內(nèi)容為:FileEvent 02 :CCTV-1(高清).xml文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步成功。 INFO-2016/5/24 7:31:33--日志內(nèi)容為:FileEvent 77 :黑龍江衛(wèi)視(高清).xml文件重新下載開始。 INFO-2016/5/24 7:31:33--日志內(nèi)容為:FileEvent 77 :黑龍江衛(wèi)視(高清).xml文件內(nèi)容已于2016/05/24 00:01進(jìn)行changed并重新下載成功。 INFO-2016/5/24 7:31:33--日志內(nèi)容為:FileEvent 77 :黑龍江衛(wèi)視(高清).xml文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步開始。 INFO-2016/5/24 7:31:33--日志內(nèi)容為:FileEvent 77 :黑龍江衛(wèi)視(高清).xml文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步成功。 INFO-2016/5/24 8:31:08--日志內(nèi)容為:8/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 9:31:08--日志內(nèi)容為:9/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 10:31:08--日志內(nèi)容為:10/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 11:31:08--日志內(nèi)容為:11/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 12:31:08--日志內(nèi)容為:12/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 13:31:08--日志內(nèi)容為:13/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 14:31:08--日志內(nèi)容為:14/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 15:31:08--日志內(nèi)容為:15/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 16:31:08--日志內(nèi)容為:16/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 17:31:08--日志內(nèi)容為:17/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 18:31:08--日志內(nèi)容為:18/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 19:31:08--日志內(nèi)容為:19/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 20:31:08--日志內(nèi)容為:20/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 21:31:08--日志內(nèi)容為:21/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 22:31:08--日志內(nèi)容為:22/31/8進(jìn)行time觸發(fā) INFO-2016/5/24 23:31:08--日志內(nèi)容為:23/31/8進(jìn)行time觸發(fā)
實(shí)現(xiàn)代碼:
下載 ftplib.dll 然后項(xiàng)目中參照引用
using FtpLib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Threading;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
private int _countFileChangeEvent = 0, _countTimerEvent = 0;
private Thread ThreadDownLoad;
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
//http://www.cnblogs.com/hfzsjz/archive/2011/01/07/1929898.html
/// <summary>
/// 服務(wù)啟動(dòng)的操作
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
try
{
EventLog.WriteEntry("監(jiān)控服務(wù)器與本地節(jié)目列表信息線程任務(wù)開始");//在系統(tǒng)事件查看器里的應(yīng)用程序事件里來(lái)源的描述
WriteInLog("監(jiān)控服務(wù)器與本地節(jié)目列表信息線程任務(wù)開始", false);
System.Timers.Timer t = new System.Timers.Timer();
// t.Interval = 60000;
t.Interval = 60 * 60 * 1000;
t.Elapsed += new System.Timers.ElapsedEventHandler(BeginDowLoad);//到達(dá)時(shí)間的時(shí)候執(zhí)行事件;
t.AutoReset = true;//設(shè)置是執(zhí)行一次(false)還是一直執(zhí)行(true);
t.Enabled = true;//是否執(zhí)行System.Timers.Timer.Elapsed事件;
t.Start();
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write(ex.Message);
throw ex;
}
}
/// <summary>
/// 定時(shí)檢查,并執(zhí)行方法
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
public void BeginDowLoad(object source, System.Timers.ElapsedEventArgs e)
{
int intMinute = e.SignalTime.Minute;
int intSecond = e.SignalTime.Second;
int intHours = e.SignalTime.Hour;
//設(shè)置 每天的07:30開始執(zhí)行程序
WriteInLog(intHours+"/"+ intMinute + "/"+ intSecond + "進(jìn)行time觸發(fā)", false);
if (intHours == 07 ) ///定時(shí)設(shè)置,判斷分時(shí)秒 && intMinute == 10
{
try
{
System.Timers.Timer tt = (System.Timers.Timer)source;
tt.Enabled = false;
DownLoadTvListInfo();
tt.Enabled = true;
}
catch (Exception err)
{
WriteInLog(err.Message, false);
}
}
}
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>
/// 服務(wù)停止的操作
/// </summary>
protected override void OnStop()
{
try
{
ThreadDownLoad.Abort();
WriteInLog("監(jiān)控服務(wù)器與本地節(jié)目列表信息線程任務(wù)停止", false);
System.Diagnostics.Trace.Write("監(jiān)控服務(wù)器與本地節(jié)目列表信息線程任務(wù)停止");
EventLog.WriteEntry("監(jiān)控服務(wù)器與本地節(jié)目列表信息線程任務(wù)停止");
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write(ex.Message);
}
}
private List<ChannelTvListInfo> lstNewTvInfo, lstOldTvInfo = new List<ChannelTvListInfo>();
private void DownLoadTvListInfo()
{
_countTimerEvent++;
WriteInLog(string.Format("TimerEvent {0}", _countTimerEvent.ToString("#00")), false);
lstNewTvInfo = listFTPFiles("222.206.159.xx", "xx", "xx");
WriteInLog(string.Format("TimerEvent {0} :共獲取{1}個(gè)節(jié)目列表信息成功。", _countTimerEvent.ToString("#00"),lstNewTvInfo.Count), false);
lstOldTvInfo = new List<ChannelTvListInfo>();
DirectoryInfo TheFolder = new DirectoryInfo(@"D:\Hello\UpLoadImg\ChannelTvXML");
foreach (FileInfo NextFile in TheFolder.GetFileSystemInfos())
{
lstOldTvInfo.Add(new ChannelTvListInfo { TVName = NextFile.Name, LastWriteTime = NextFile.LastWriteTime.ToString("yyyy/MM/dd HH:mm") });
}
Thread.Sleep(60000);
ThreadDownLoad = new Thread(new ThreadStart(Test));
ThreadDownLoad.Start();
WriteInLog("服務(wù)器與本地節(jié)目列表信息進(jìn)行對(duì)比開始。", false);
System.Diagnostics.Trace.Write("線程任務(wù)開始");
}
public void Test()
{
try
{
var result = lstNewTvInfo.Except(lstOldTvInfo, new ProductComparer()).ToList();
WriteInLog("得到要更新的節(jié)目列表共"+ result.Count+"個(gè)", false);
if (result.Count > 0)
{
foreach (var item in result)
{
_countFileChangeEvent++;
WriteInLog(string.Format("FileEvent {0} :{1}文件重新下載開始。", _countFileChangeEvent.ToString("#00"),
item.TVName), false);
new FtpHelper().DownloadFtpFile("xx", "xx", "222.206.159.xx", @"D:\Hello\UpLoadImg\ChannelTvXML", item.TVName);
WriteInLog(string.Format("FileEvent {0} :{1}文件內(nèi)容已于{2}進(jìn)行{3}", _countFileChangeEvent.ToString("#00"),
item.TVName, item.LastWriteTime, "changed并重新下載成功。"), false);
WriteInLog(string.Format("FileEvent {0} :{1}文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步開始。", _countFileChangeEvent.ToString("#00"),
item.TVName), false);
File.SetLastWriteTime(@"D:\Hello\UpLoadImg\ChannelTvXML\" + item.TVName,
Convert.ToDateTime(new FtpHelper().GetDateTimestamp("222.206.159.xx", item.TVName, "xx", "quanmeiti").xx("yyyy/MM/dd hh:mm tt")));
WriteInLog(string.Format("FileEvent {0} :{1}文件下載后的修改時(shí)間開始與服務(wù)器修改時(shí)間同步成功。", _countFileChangeEvent.ToString("#00"),
item.TVName), false);
}
}
else
{
WriteInLog("暫無(wú)服務(wù)器電視節(jié)目列表更新", false);
}
}
catch { }
Thread.Sleep(60000);
}
/// <summary>
/// 寫入文件操作
/// </summary>
/// <param name="msg">寫入內(nèi)容</param>
/// <param name="IsAutoDelete">是否刪除</param>
private void WriteInLog(string msg, bool IsAutoDelete)
{
try
{
string logFileName = @"D:\Hello\UpLoadImg\ChannelLog\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() + "--日志內(nèi)容為:" + msg + "\r\n");
sw.Flush();
sw.Close();
}
}
catch (Exception ex)
{
ex.ToString();
}
}
}
}
實(shí)現(xiàn)從FTP下載文件方法
/// <summary>
///從ftp服務(wù)器上下載文件的功能
/// </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;
}
}
設(shè)置widnwos服務(wù)就不多介紹了。如下圖:


以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#中Write()和WriteLine()的區(qū)別分析
這篇文章主要介紹了C#中Write()和WriteLine()的區(qū)別分析,需要的朋友可以參考下2020-11-11
WPF利用ValueConverter實(shí)現(xiàn)值轉(zhuǎn)換器
值轉(zhuǎn)換器在WPF開發(fā)中是非常常見的,值轉(zhuǎn)換器可以幫助我們很輕松地實(shí)現(xiàn),界面數(shù)據(jù)展示的問(wèn)題。本文將通過(guò)WPF?ValueConverter實(shí)現(xiàn)簡(jiǎn)單的值轉(zhuǎn)換器,希望對(duì)大家有所幫助2023-03-03
通過(guò)容器擴(kuò)展屬性IExtenderProvider實(shí)現(xiàn)WinForm通用數(shù)據(jù)驗(yàn)證組件
這篇文章介紹了通過(guò)容器擴(kuò)展屬性IExtenderProvider實(shí)現(xiàn)WinForm通用數(shù)據(jù)驗(yàn)證組件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12
C# ping網(wǎng)絡(luò)IP 實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)檢測(cè)的方法
下面小編就為大家?guī)?lái)一篇C# ping網(wǎng)絡(luò)IP 實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)檢測(cè)的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
C# WinForm中Panel實(shí)現(xiàn)用鼠標(biāo)操作滾動(dòng)條的實(shí)例方法
由于在WinForm中Panel不能直接響應(yīng)鼠標(biāo)的滾動(dòng)事件,只好采用捕獲窗體的滾動(dòng)事件。2013-03-03
如何使用C#將Tensorflow訓(xùn)練的.pb文件用在生產(chǎn)環(huán)境詳解
這篇文章主要給大家介紹了關(guān)于如何使用C#將Tensorflow訓(xùn)練的.pb文件用在生產(chǎn)環(huán)境的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11

