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

     1.引言

          实现一个FTP 文件的下载功能。

     2.初步构想

               a)采用类库的方式实现FTP 文件的下载,在界面层实现类库的调用。

               b)在文件下载的开始或结束能够反馈当前下载文件名、下载文件大小以及下载文件耗时等信息。

               c)在文件下载的过程中能够实现文件下载进度显示功能。

     3.FTP 类库实现

               第一步:创建工程

                    创建命名为LibDldFile类库工程。

                第二步:

                    在工程中建立IDldFile.cs 接口文件和FtpDldFile.cs 文件

                    定义文件下载接口

ContractedBlock.gif ExpandedBlockStart.gif Code
interface IDldFile
    {
        
/// <summary>
        
/// 下载文件列表
        
/// </summary>
        List<string> DldFilePathList { get;set;}

        
/// <summary>
        
/// 下载文件
        
/// </summary>
        
/// <returns></returns>
        void Download();
    }

          第三步:初步实现FTP 下载功能

               下面的FTPDldFile 类能够初步实现FTP 文件的下载。

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

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

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

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

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

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

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

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

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

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

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

        
#region IDldFile 成员

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

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

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

        
public void Download()
        {
            
//_dldFileList = new List<string>();
            
//_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[_ftpDldSize];

                        
//当前已下载文件大小
                        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
    }

 

          第四步:

               实现下载文件过程中信息反馈(包括下载文件信息、时间和百分比)

               首先,在接口中定义事件和委托:

ContractedBlock.gif ExpandedBlockStart.gif Code
/// <summary>
    
/// 委托,用于标识提示用户是否需要覆盖当前文件
    
/// </summary>
    
/// <param name="fileName">覆盖文件名称</param>
    
/// <returns></returns>
    public delegate bool DelegateIsReplace(string fileName);

    
/// <summary>
    
/// 委托,用于标识当前文件下载百分比
    
/// </summary>
    
/// <param name="dldPercentage">当前文件下载百分比</param>
    public delegate void DelegateDldPercentage(double dldPercentage);

    
/// <summary>
    
/// 委托,用于标识下载文件信息
    
/// </summary>
    
/// <param name="message"></param>
    public delegate void DelegateDldMessage(string message);

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

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

        
/// <summary>
        
/// 下载文件信息
        
/// </summary>
        event DelegateDldMessage EDldMessage;
    }

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

ContractedBlock.gif ExpandedBlockStart.gif Code
public void Download()
        {
            
//_dldFileList = new List<string>();
            
//_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[_ftpDldSize];

                        
//当前已下载文件大小
                        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文件不能成功,本来想截个图的。)

               界面中包括保存文件路径和下载按钮,和反馈信息显示栏及进度条。

               调用类库代码: 

ContractedBlock.gif ExpandedBlockStart.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;
        }

        
/// <summary>
        
/// 进度条
        
/// </summary>
        
/// <param name="dldPercentage"></param>
        void ftpDldFile_EDldPercentage(double dldPercentage)
        {
            
this.toolStripProgressBar1.Value = (Int32)dldPercentage;
            Application.DoEvents();
        }

        
/// <summary>
        
/// 反馈信息
        
/// </summary>
        
/// <param name="message"></param>
        void ftpDldFile_EDldMessage(string message)
        {
            
this.toolStripStatusLabel1.Text = message;
            Application.DoEvents();
        }

        
/// <summary>
        
/// 是否覆盖原来文件
        
/// </summary>
        
/// <param name="fileName"></param>
        
/// <returns></returns>
        bool ftpDldFile_EIsReplace(string fileName)
        {
            
if (MessageBox.Show("当前" + fileName + "已经存在,是否覆盖?""确认信息", MessageBoxButtons.YesNo) == DialogResult.Yes)
                
return true;
            
else
                
return false;
        }

     

     我这里只是一步一步介绍了编写一个简单FTP 文件下载类库的过程,希望能够对一部分人有帮助.其后附源码:

FTP 文件下载类库

转载于:https://www.cnblogs.com/stan0714/archive/2008/12/03/1347044.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
例子: 调用方法,目前只用上传功能:     定义全局私有变量:  private clsFTP cf;    按钮事件:         private void btn_upFile_Click(object sender, EventArgs e)         {             lb_upload.Text = "正在上传文件,请等待...";              cf = new clsFTP(new Uri("http://www.cnblogs.com/zhangjun1130/admin/ftp://192.168.43.55/"), "temp", "temp");             string localFile = Application.StartupPath.ToString() + "http://www.cnblogs.com/zhangjun1130/admin/file://output//zt.rar";              cf.UploadProgressChanged+=new clsFTP.De_UploadProgressChanged(cf_UploadProgressChanged);              cf.UploadFileCompleted+=new clsFTP.De_UploadFileCompleted(cf_UploadFileCompleted);              cf.UploadFileAsync(localFile, true);  //调用异步传输,若有文件存在则覆盖。         }    事件捆绑,反映上传进度:         public void cf_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)         {             this.pgrBarFileUpload.Maximum = (int)e.TotalBytesToSend;             this.pgrBarFileUpload.Value =(int) e.BytesSent;             lb_upload.Text = string.Format("文件总大小:{0}k,已经上传: {1}k。", e.TotalBytesToSend/1024,e.BytesSent/1024);         }         public void cf_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)         {                         try             {                 lb_upload.Text = "无法连接到服务器,或者用户登陆失败!";                 lb_error.Text =e.Error.Message.ToString();             }             catch             {                 lb_upload.Text = "文件上传成功!";                 lb_error.Text = "";             }         } 点击连接:http:##www.cnblogs.com/zhangjun1130/archive/2010/03/24/1693932.html

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值