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[strArray.Length - 1];
}
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[_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
}
第四步:
实现下载文件过程中信息反馈(包括下载文件信息、时间和百分比)
首先,在接口中定义事件和委托:
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[_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文件不能成功,本来想截个图的。)
界面中包括保存文件路径和下载按钮,和反馈信息显示栏及进度条。
调用类库代码:
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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com