一步一步编写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]