昊漫玉 发表于 2015-5-26 11:52:01

一步一步编写FTP 文件下载类库(附源码)

     1.引言
            实现一个FTP 文件的下载功能。
     2.初步构想
                 a)采用类库的方式实现FTP 文件的下载,在界面层实现类库的调用。
                 b)在文件下载的开始或结束能够反馈当前下载文件名、下载文件大小以及下载文件耗时等信息。
                 c)在文件下载的过程中能够实现文件下载进度显示功能。
     3.FTP 类库实现
   第一步:创建工程
                    创建命名为LibDldFile类库工程。
  第二步:
  在工程中建立IDldFile.cs 接口文件和FtpDldFile.cs 文件
                    定义文件下载接口

Code
interface IDldFile
    {
      ///
      /// 下载文件列表
      ///
      List DldFilePathList { get;set;}

      ///
      /// 下载文件
      ///
      ///
      void Download();
    }  第三步:初步实现FTP 下载功能
  下面的FTPDldFile 类能够初步实现FTP 文件的下载。

Code
public class FtpDldFile : IDldFile
    {
      private string _ftpLoginUser = string.Empty;
      private string _ftpLoginPwd = string.Empty;
      private string _dldFileSaveDir = string.Empty;
      private List _dldFileList = null;
      private UInt32 _ftpDldSize = 1024;

      ///
      /// 创建FTP 下载对象(文件保存路径默认为当前程序启动路径)
      ///
      /// 下载文件路径列表
      /// FTP 登录用户
      /// FTP 登录密码
      public FtpDldFile(List dldFileList, string ftpLoginUser, string ftpLoginPwd)
      {
            _dldFileList = dldFileList;
            _ftpLoginPwd = ftpLoginPwd;
            _ftpLoginUser = ftpLoginUser;
      }

      ///
      /// 创建FTP 下载对象
      ///
      /// 下载文件路径列表
      /// FTP 登录用户
      /// FTP 登录密码
      /// 下载文件保存路径
      public FtpDldFile(List dldFileList, string ftpLoginUser, string ftpLoginPwd, string dldFileSaveDir)
      {
            _dldFileList = dldFileList;
            _ftpLoginPwd = ftpLoginPwd;
            _ftpLoginUser = ftpLoginUser;
            _dldFileSaveDir = dldFileSaveDir;
      }

      ///
      /// 下载文件保存路径
      ///
      public string DldFileSaveDir
      {
            get
            {
                if (_dldFileSaveDir == string.Empty)
                  _dldFileSaveDir = AppDomain.CurrentDomain.BaseDirectory;

                //确保最后位为\
                if (_dldFileSaveDir.Substring(_dldFileSaveDir.Length - 1) != @"\")
                  _dldFileSaveDir += "\\";

                return _dldFileSaveDir;
            }
            set
            {
                _dldFileSaveDir = value;
            }
      }

      ///
      /// FTP 登录用户
      ///
      public string FtpLoginUser
      {
            get
            {
                if (_ftpLoginUser == string.Empty)
                  throw new Exception("The Ftp LoginUser is null");

                return _ftpLoginUser;
            }
            set
            {
                _ftpLoginUser = value;
            }
      }

      ///
      /// FTP 登录密码
      ///
      public string FtpLoginPwd
      {
            get
            {
                if (_ftpLoginPwd == string.Empty)
                  throw new Exception("The Ftp LoginPwd is null");

                return _ftpLoginPwd;
            }
            set
            {
                _ftpLoginPwd = value;
            }
      }

      ///
      /// 下载FTP 文件每次读取大小
      ///
      public UInt32 FtpDldSize
      {
            get
            {
                return _ftpDldSize;
            }
            set
            {
                _ftpDldSize = value;
            }
      }

      #region IDldFile 成员

      public List DldFilePathList
      {
            get
            {
                if (_dldFileList == null)
                  _dldFileList = new List();

                return _dldFileList;
            }
            set
            {
                _dldFileList = value;
            }
      }

      ///
      /// 将指定的FTP 路径中目录路径和文件名称分离,获取文件名称
      ///
      ///
      ///
      public static string ConvertPathToFileName(string ftpPath)
      {
            string[] strArray = ftpPath.Split(new char[] { '/' });
            return strArray;
      }

      public void Download()
      {
            //_dldFileList = new List();
            //_dldFileList.Add(@"ftp://192.168.0.21/incoming/1.txt");
            //_ftpLoginPwd = "IECAS12345678";
            //_ftpLoginUser = "xiangwei";

            string curFileName = string.Empty;
            try
            {
                FtpWebRequest request;
                FtpWebResponse response;

                foreach (string strFile in DldFilePathList)
                {
                  curFileName = ConvertPathToFileName(strFile);

                  //校验文件是否存在,如果存在给出提示用户是否覆盖
                  if (System.IO.File.Exists(DldFileSaveDir + curFileName))
                  {
                        //通过委托获取用户是否同意覆盖
                        if (!EIsReplace(strFile))
                        {
                            continue;
                        }
                  }
                  
                  request = (FtpWebRequest)WebRequest.Create(strFile);
                  request.KeepAlive = false;
                  request.Credentials = new NetworkCredential(_ftpLoginUser, _ftpLoginPwd);

                  using (response = (FtpWebResponse)request.GetResponse())
                  {
                        Stream data = response.GetResponseStream();

                        //文件大小
                        long fileLength = response.ContentLength;

                        //文件输出路径
                        string targetPath = DldFileSaveDir + curFileName;

                        //每次下载文件大小
                        byte[] byteBuffer = new byte;

                        //当前已下载文件大小
                        long currentDldBytes = 0;
                        //当前已下载文件百分比
                        double currentPercentage = 0;

                        using (FileStream output = new FileStream(targetPath, FileMode.OpenOrCreate))
                        {
                            int bytesRead = 0;
                            do
                            {
                              //上报下载文件百分比

                              bytesRead = data.Read(byteBuffer, 0, byteBuffer.Length);
                              if (bytesRead > 0)
                              {
                                    output.Write(byteBuffer, 0, bytesRead);
                              }

                              currentDldBytes += bytesRead;

                              currentPercentage = ((double)currentDldBytes / (double)fileLength) * 100;
                            }
                            while (bytesRead > 0);
                        }
                  }
                }
            }
            catch (WebException e)
            {
                throw new WebException("Download " + curFileName + " error has occored!The exception message is " + e.Message);
            }
      }

      #endregion
    }  
  第四步:
  实现下载文件过程中信息反馈(包括下载文件信息、时间和百分比)
  首先,在接口中定义事件和委托:

Code
///
    /// 委托,用于标识提示用户是否需要覆盖当前文件
    ///
    /// 覆盖文件名称
    ///
    public delegate bool DelegateIsReplace(string fileName);

    ///
    /// 委托,用于标识当前文件下载百分比
    ///
    /// 当前文件下载百分比
    public delegate void DelegateDldPercentage(double dldPercentage);

    ///
    /// 委托,用于标识下载文件信息
    ///
    ///
    public delegate void DelegateDldMessage(string message);

    interface IDldFile
    {
      List DldFilePathList { get;set;}
      
      ///
      /// 下载文件
      ///
      ///
      void Download();
      
      ///
      /// 事件,用于提示用户是否覆盖已经存在文件
      ///
      event DelegateIsReplace EIsReplace;

      ///
      /// 当前下载文件百分比
      ///
      event DelegateDldPercentage EDldPercentage;

      ///
      /// 下载文件信息
      ///
      event DelegateDldMessage EDldMessage;
    }  原来的下载类再次实现该接口信息后,并且在下载Download 方法中调用事件:

Code
public void Download()
      {
            //_dldFileList = new List();
            //_dldFileList.Add(@"ftp://192.168.0.21/incoming/1.txt");
            //_ftpLoginPwd = "IECAS12345678";
            //_ftpLoginUser = "xiangwei";

            string curFileName = string.Empty;
            try
            {
                FtpWebRequest request;
                FtpWebResponse response;

                foreach (string strFile in DldFilePathList)
                {
                  curFileName = ConvertPathToFileName(strFile);

                  //校验文件是否存在,如果存在给出提示用户是否覆盖
                  if (System.IO.File.Exists(DldFileSaveDir + curFileName))
                  {
                        //通过委托获取用户是否同意覆盖
                        if (!EIsReplace(strFile))
                        {
                            continue;
                        }
                  }
                  
                  request = (FtpWebRequest)WebRequest.Create(strFile);
                  request.KeepAlive = false;
                  request.Credentials = new NetworkCredential(_ftpLoginUser, _ftpLoginPwd);

                  using (response = (FtpWebResponse)request.GetResponse())
                  {
                        Stream data = response.GetResponseStream();

                        //文件大小
                        long fileLength = response.ContentLength;

                        //文件输出路径
                        string targetPath = DldFileSaveDir + curFileName;

                        //每次下载文件大小
                        byte[] byteBuffer = new byte;

                        //当前已下载文件大小
                        long currentDldBytes = 0;
                        //当前已下载文件百分比
                        double currentPercentage = 0;

                        //开始下载文件时间
                        DateTime startTime = DateTime.Now;
                        TimeSpan timeSpan;
                        using (FileStream output = new FileStream(targetPath, FileMode.OpenOrCreate))
                        {
                            int bytesRead = 0;

                            //上报开始下载文件信息
                            EDldMessage("开始下载文件:" + curFileName + " 文件大小:" + fileLength );
                            do
                            {
                              //上报下载文件百分比
                              EDldPercentage(currentPercentage);

                              bytesRead = data.Read(byteBuffer, 0, byteBuffer.Length);
                              if (bytesRead > 0)
                              {
                                    output.Write(byteBuffer, 0, bytesRead);
                              }

                              currentDldBytes += bytesRead;

                              currentPercentage = ((double)currentDldBytes / (double)fileLength) * 100;
                            }
                            while (bytesRead > 0);

                            timeSpan = DateTime.Now - startTime;
                            EDldMessage("下载" + curFileName + "完成,耗时:" + timeSpan.Minutes.ToString() + " 分 " + timeSpan.Seconds + " 秒 " + timeSpan.Milliseconds + "毫秒");
                        }
                  }
                }
            }
            catch (WebException e)
            {
                throw new WebException("Download " + curFileName + " error has occored!The exception message is " + e.Message);
            }
      }  第五步:实现界面层       
  好了,一个简单的FTP 下载类库已经编写好了,我们再来写一个界面层调用程序来实现这个类库的调用吧.
  ( 不知道是不是博客园的问题,我这边上传JPG或者GIF文件不能成功,本来想截个图的。)
  界面中包括保存文件路径和下载按钮,和反馈信息显示栏及进度条。
  调用类库代码:

Code
private void btnSure_Click(object sender, EventArgs e)
      {
            FtpDldFile ftpDldFile = new FtpDldFile(DldFileList, _ftpLoginUser, _ftpLoginPwd, this.textBox1.Text);

            ftpDldFile.EIsReplace += new DelegateIsReplace(ftpDldFile_EIsReplace);
            ftpDldFile.EDldMessage += new DelegateDldMessage(ftpDldFile_EDldMessage);
            ftpDldFile.EDldPercentage += new DelegateDldPercentage(ftpDldFile_EDldPercentage);

            this.btnSure.Enabled = false;
            this.btnClose.Enabled = false;
            ftpDldFile.Download();
            this.btnSure.Enabled = true;
            this.btnClose.Enabled = true;
      }

      ///
      /// 进度条
      ///
      ///
      void ftpDldFile_EDldPercentage(double dldPercentage)
      {
            this.toolStripProgressBar1.Value = (Int32)dldPercentage;
            Application.DoEvents();
      }

      ///
      /// 反馈信息
      ///
      ///
      void ftpDldFile_EDldMessage(string message)
      {
            this.toolStripStatusLabel1.Text = message;
            Application.DoEvents();
      }

      ///
      /// 是否覆盖原来文件
      ///
      ///
      ///
      bool ftpDldFile_EIsReplace(string fileName)
      {
            if (MessageBox.Show("当前" + fileName + "已经存在,是否覆盖?", "确认信息", MessageBoxButtons.YesNo) == DialogResult.Yes)
                return true;
            else
                return false;
      }  
  我这里只是一步一步介绍了编写一个简单FTP 文件下载类库的过程,希望能够对一部分人有帮助.其后附源码:
  FTP 文件下载类库
页: [1]
查看完整版本: 一步一步编写FTP 文件下载类库(附源码)