欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#开发windows服务实现自动从FTP服务器下载文件

程序员文章站 2022-06-21 09:44:29
最近在做一个每天定点从ftp自动下载节目.xml并更新到数据库的功能。首先想到用 filesystemwatcher来监控下载到某个目录中的文件是否发生改变,如果改变就执行...

最近在做一个每天定点从ftp自动下载节目.xml并更新到数据库的功能。首先想到用 filesystemwatcher来监控下载到某个目录中的文件是否发生改变,如果改变就执行相应的操作,然后用timer来设置隔多长时间来下载。后来又想想,用windwos服务来实现。

效果图:

C#开发windows服务实现自动从FTP服务器下载文件

执行的log日志:

info-2016/5/24 0:30:07--日志内容为:0/30/7进行time触发
info-2016/5/24 1:30:07--日志内容为:1/30/7进行time触发
info-2016/5/24 2:30:07--日志内容为:2/30/7进行time触发
info-2016/5/24 3:30:07--日志内容为:3/30/7进行time触发
info-2016/5/24 4:30:07--日志内容为:4/30/7进行time触发
info-2016/5/24 5:30:07--日志内容为:5/30/7进行time触发
info-2016/5/24 6:30:07--日志内容为:6/30/7进行time触发
info-2016/5/24 7:30:07--日志内容为:7/30/7进行time触发
info-2016/5/24 7:30:07--日志内容为:timerevent 01
info-2016/5/24 7:30:07--日志内容为:timerevent 01 :共获取77个节目列表信息成功。
info-2016/5/24 7:31:08--日志内容为:服务器与本地节目列表信息进行对比开始。
info-2016/5/24 7:31:08--日志内容为:得到要更新的节目列表共77个
info-2016/5/24 7:31:08--日志内容为:fileevent 01 :btv-1(高清).xml文件重新下载开始。
info-2016/5/24 7:31:08--日志内容为:fileevent 01 :btv-1(高清).xml文件内容已于2016/05/24 00:01进行changed并重新下载成功。
info-2016/5/24 7:31:08--日志内容为:fileevent 01 :btv-1(高清).xml文件下载后的修改时间开始与服务器修改时间同步开始。
info-2016/5/24 7:31:08--日志内容为:fileevent 01 :btv-1(高清).xml文件下载后的修改时间开始与服务器修改时间同步成功。
info-2016/5/24 7:31:08--日志内容为:fileevent 02 :cctv-1(高清).xml文件重新下载开始。
info-2016/5/24 7:31:08--日志内容为:fileevent 02 :cctv-1(高清).xml文件内容已于2016/05/24 00:01进行changed并重新下载成功。
info-2016/5/24 7:31:08--日志内容为:fileevent 02 :cctv-1(高清).xml文件下载后的修改时间开始与服务器修改时间同步开始。
info-2016/5/24 7:31:08--日志内容为:fileevent 02 :cctv-1(高清).xml文件下载后的修改时间开始与服务器修改时间同步成功。
info-2016/5/24 7:31:33--日志内容为:fileevent 77 :黑龙江卫视(高清).xml文件重新下载开始。
info-2016/5/24 7:31:33--日志内容为:fileevent 77 :黑龙江卫视(高清).xml文件内容已于2016/05/24 00:01进行changed并重新下载成功。
info-2016/5/24 7:31:33--日志内容为:fileevent 77 :黑龙江卫视(高清).xml文件下载后的修改时间开始与服务器修改时间同步开始。
info-2016/5/24 7:31:33--日志内容为:fileevent 77 :黑龙江卫视(高清).xml文件下载后的修改时间开始与服务器修改时间同步成功。
info-2016/5/24 8:31:08--日志内容为:8/31/8进行time触发
info-2016/5/24 9:31:08--日志内容为:9/31/8进行time触发
info-2016/5/24 10:31:08--日志内容为:10/31/8进行time触发
info-2016/5/24 11:31:08--日志内容为:11/31/8进行time触发
info-2016/5/24 12:31:08--日志内容为:12/31/8进行time触发
info-2016/5/24 13:31:08--日志内容为:13/31/8进行time触发
info-2016/5/24 14:31:08--日志内容为:14/31/8进行time触发
info-2016/5/24 15:31:08--日志内容为:15/31/8进行time触发
info-2016/5/24 16:31:08--日志内容为:16/31/8进行time触发
info-2016/5/24 17:31:08--日志内容为:17/31/8进行time触发
info-2016/5/24 18:31:08--日志内容为:18/31/8进行time触发
info-2016/5/24 19:31:08--日志内容为:19/31/8进行time触发
info-2016/5/24 20:31:08--日志内容为:20/31/8进行time触发
info-2016/5/24 21:31:08--日志内容为:21/31/8进行time触发
info-2016/5/24 22:31:08--日志内容为:22/31/8进行time触发
info-2016/5/24 23:31:08--日志内容为:23/31/8进行time触发

实现代码:

下载 ftplib.dll 然后项目中参照引用

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>
 /// 服务启动的操作
 /// </summary>
 /// <param name="args"></param>
 protected override void onstart(string[] args)
 {
 try
 {
 eventlog.writeentry("监控服务器与本地节目列表信息线程任务开始");//在系统事件查看器里的应用程序事件里来源的描述 
 writeinlog("监控服务器与本地节目列表信息线程任务开始", false);
 system.timers.timer t = new system.timers.timer();
 // t.interval = 60000;
  t.interval = 60 * 60 * 1000;  
 t.elapsed += new system.timers.elapsedeventhandler(begindowload);//到达时间的时候执行事件; 
 t.autoreset = true;//设置是执行一次(false)还是一直执行(true); 
 t.enabled = true;//是否执行system.timers.timer.elapsed事件; 
 t.start();
 }
 catch (exception ex)
 {
 system.diagnostics.trace.write(ex.message);
 throw ex;
 }
 }
 /// <summary> 
 /// 定时检查,并执行方法 
 /// </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;
 //设置 每天的07:30开始执行程序
 writeinlog(inthours+"/"+ intminute + "/"+ intsecond + "进行time触发", false);
 if (inthours == 07 ) ///定时设置,判断分时秒    && 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>
 /// 服务停止的操作
 /// </summary>
 protected override void onstop()
 {
 try
 {
 threaddownload.abort();
 writeinlog("监控服务器与本地节目列表信息线程任务停止", false);
 system.diagnostics.trace.write("监控服务器与本地节目列表信息线程任务停止");
 eventlog.writeentry("监控服务器与本地节目列表信息线程任务停止");
 }
 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}个节目列表信息成功。", _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("服务器与本地节目列表信息进行对比开始。", false);
 system.diagnostics.trace.write("线程任务开始");
 }
 
 public void test()
 {
 try
 {
 var result = lstnewtvinfo.except(lstoldtvinfo, new productcomparer()).tolist();
 writeinlog("得到要更新的节目列表共"+ result.count+"个", 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}文件内容已于{2}进行{3}", _countfilechangeevent.tostring("#00"),
        item.tvname, item.lastwritetime, "changed并重新下载成功。"), false);
 
  writeinlog(string.format("fileevent {0} :{1}文件下载后的修改时间开始与服务器修改时间同步开始。", _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}文件下载后的修改时间开始与服务器修改时间同步成功。", _countfilechangeevent.tostring("#00"),
 item.tvname), false);
 
  }
 }
 else
 {
  writeinlog("暂无服务器电视节目列表更新", false);
 }
 
 }
 catch { }
 thread.sleep(60000);
 }
 
 /// <summary>
 /// 写入文件操作
 /// </summary>
 /// <param name="msg">写入内容</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() + "--日志内容为:" + msg + "\r\n");
  sw.flush();
  sw.close();
 }
 }
 catch (exception ex)
 {
 ex.tostring();
 }
 }
 }
 
}

实现从ftp下载文件方法

 /// <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;
 }
 }

设置widnwos服务就不多介绍了。如下图:

C#开发windows服务实现自动从FTP服务器下载文件

C#开发windows服务实现自动从FTP服务器下载文件

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。