使用MFC对FTP文件或者文件夹进行下载、断点续传等功能的个人理解
来源:互联网 发布:湘潭软件职业技术学院 编辑:程序博客网 时间:2024/05/20 23:04
函数功能:VS2010 —— MFC —— 基于对话框 —— 输入ftp服务器数据、本地下载路径 —— 连接后显示ftp服务器文件情况在列表控件上,有操作功能
从ftp服务器下载指定文件或文件夹到指定的本地路径,保存需要下载的文件大小 ,然后计算本地下载文件大小,比对下载完成度 ,有错误提示。
断点续传功能在第二种方法才有。
使用到的头文件:
#include "stdafx.h"
#include "ftpDL.h"
#include "ftpDLDlg.h"
#include "afxdialogex.h"
#include "afxinet.h"
#include "afxwin.h"
#include <vector>
#include "TipDlg.h" //这个是建立的一个新的对话框,主要在双击的时候弹出选择
教程在此:http://www.jizhuomi.com/software/160.html
全局变量定义:
vector <CString> m_string; //创建Vector保存目录
vector <CString> m_dotstring; //保存文件
vector <CString> V_counterpart; //进入下一层按钮时创建当前层副本,记录列表项的数据
CString m_ftppath; //函数需要的输入路径,及搜索当前路径的文件以及目录
vector <CString> V_ftppath; //副本保存路径,显示下一层时用m_ftppath加上**,返回上层时减去**
int n; //记录当前显示的层数,根目录为0层,
int ig = 0 ; //控制一下创建目录选择哪个
int dir[20]; //创建一个可以保存20个数的数组来保存目录存储时每一层有多少个文件和目录,现在可以存储10层目录,控制这个数组大小可以控制目录的层数
int size[20]; //存储每层多少目录,20表示可以存储20层目录的数据,即每层目录内的文件数量保存在一个数组元素中
LONGLONG m_dirsize = 0; //保存文件的大小
LONGLONG m_fdirsize = 0; //保存ftp要下载的文件或文件夹大小
int nDownloaded; //断点续传的控制
对话框部分的变量输入:(有一项控件是作为重新绘制使用的,如果不需要只需要弄好输入变量的)
DDX_Control(pDX, IDC_localpt_STATIC, m_localpathpos);
DDX_Text(pDX, IDC_localpath_EDIT1, m_localpath);
DDX_Control(pDX, IDC_localpath_EDIT1, m_editlocalpath);
DDX_Control(pDX, IDC_ftppt_STATIC, m_ftppt);
DDX_Text(pDX, IDC_ftpadress_EDIT1, m_ftpadress);
DDX_Control(pDX,IDC_ftpadress_EDIT1, m_editftpadress);
DDX_Control(pDX, IDC_usernm_STATIC, m_usernm);
DDX_Text(pDX, IDC_username_EDIT2, m_username);
DDX_Control(pDX,IDC_username_EDIT2,m_editusername);
DDX_Control(pDX,IDC_passwd_STATIC, m_passwd);
DDX_Text(pDX, IDC_password_EDIT3, m_password);
DDX_Control(pDX,IDC_password_EDIT3,m_editpassword);
DDX_Control(pDX,IDC_pt_STATIC,m_pt);
DDX_Text(pDX, IDC_port_EDIT4, m_port);
DDX_Control(pDX, IDC_port_EDIT4,m_editport);
DDX_Control(pDX,IDC_Fareason_STATIC,m_Fareason);
DDX_Text(pDX, IDC_Freason_EDIT5, m_Freason);
DDX_Control(pDX,IDC_Freason_EDIT5,m_editFreason);
DDX_Control(pDX, IDC_dirshow_LIST1, m_listBox);
DDX_Control(pDX, IDC_RIGHTWND,m_rightwnd);
DDX_Control(pDX, IDC_connect_BUTTON,m_btconnect);
DDX_Control(pDX, IDC_shownextdir_BUTTON,m_btshownextdir);
DDX_Control(pDX, IDC_Return_BUTTON,m_btreturn);
DDX_Control(pDX, IDC_download_BUTTON,m_btdownload);
DDX_Control(pDX, IDCANCEL, m_btcancel);
连接ftp服务器,显示目录在list控件中:
BOOL FtpList(CString &ftppath,CString ftpaddress,CString username,CString &Freason,CString password,int port) //定义ftp目录遍历函数
{
CInternetSession sess(_T("List Files Session")); //创建CInternetSession类对象 sess
CFtpConnection *pFtpCon=NULL; //创建cftpconnection类对象指针* pFtpCon 为默认值
try
{
pFtpCon=sess.GetFtpConnection(ftpaddress,username,password,port); //调用GetFtpConnection连接FTP服务器
if(pFtpCon==NULL)
{
Freason = "connection is false";
return FALSE;
}
CFtpFileFind ftpDirFinder (pFtpCon); //创建CFtpFileFind类对象ftpDirFinder,"()"内为格式中要求填写的cftpconnection类对象指针
CStringArray m_dir1; //定义一个数组保存目录,一个保存文件
CStringArray m_dir2;
BOOL bWorking = ftpDirFinder.FindFile(ftppath);
while (bWorking) //循环进行目录调用,保存FTP第一层文件或者文件夹在数组中
{
bWorking=ftpDirFinder.FindNextFile(); //循环条件:如果bWork为找不到下一个文件了,循环跳出
if(ftpDirFinder.IsDots()) //这一段为跳过"."和"..“文件,不跳过会无线重复。
{
continue;
}
if(ftpDirFinder.IsDirectory())
{
m_dir1.Add( ftpDirFinder.GetFileName()); //如果是目录的话,就保存在数组1
//只需要一层,不用递归,如果用递归,则遍历多层。
}
else //找到的不是目录(即文件),保存在数组2
{
m_dir2.Add( ftpDirFinder.GetFileName());
//文件保存在数组2中
}
}
ftpDirFinder.Close(); //关闭ftp连接,开始显示数组中每一项目录
for (int i=0;i<m_dir1.GetSize();i++) //通过循环保存每一项目录或者文件
{
m_string.push_back(m_dir1.GetAt(i)); //目录保存在m_string中
}
for (int j=0;j<m_dir2.GetSize();j++)
{
m_dotstring.push_back(m_dir2.GetAt(j)); //文件保存在m_dotstring中
}
}
catch(CInternetException* pEx)
{
TCHAR sz[1024];
pEx->GetErrorMessage(sz, 1024);
Freason = sz;
printf("%s",sz);
pEx->Delete();
}
if (pFtpCon != NULL)
{
pFtpCon->Close();
delete pFtpCon;
pFtpCon = NULL;
}
return TRUE;
}
下载部分主程序:
下载程序使用到3个另外的自定义函数,一个为检测目录是否存在,另一个是创建多级目录,此2个函数来自csdn的博客,还一个是文件大小比对的自写函数
检测函数:
BOOL FolderExists(CString s)
{
DWORD attr;
attr = GetFileAttributes(s);
return (attr != (DWORD)(-1) ) &&
( attr & FILE_ATTRIBUTE_DIRECTORY);
}
创建目录函数:
BOOL CreateMuliteDirectory(CString P)
{
int len=P.GetLength();
if ( len <2 )
return false;
if('/'==P[len-1])
{
P=P.Left(len-1);
len=P.GetLength();
}
if ( len <=0 )
return false;
if (len <=3)
{
if (FolderExists(P))
return true;
else
return false;
}
if (FolderExists(P))
return true;
CString Parent;
Parent=P.Left(P.ReverseFind('/') );
if(Parent.GetLength()<=0)
return false;
BOOL Ret=CreateMuliteDirectory(Parent);
if(Ret)
{
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=0;
Ret=(CreateDirectory(P,&sa)==TRUE);
return Ret;
}
else
return FALSE;
}
int LocalFileCompa(CString folderpath,LONGLONG netfilesize) //下载文档是文件夹的时候
{
int index = folderpath.ReverseFind('/');
if(index == -1)
{
return FALSE;
}
CFileFind finder;
CString str_path(folderpath);
str_path += _T("\\*.*");
vector <LONGLONG> V_nsize;
BOOL bWorking = finder.FindFile(folderpath);
while (bWorking)
{
bWorking = finder.FindNextFile();
if (finder.IsDots())
{
continue;
}
else if(finder.IsDirectory())
{
LocalFileCompa(finder.GetFilePath(),netfilesize);
}
else
{
LONGLONG m_filesize;
m_filesize = finder.GetLength();
V_nsize.push_back(m_filesize);
}
}
LONGLONG m_sumsize = 0;
for(int i=0;i<V_nsize.size();i++)
{
m_sumsize += V_nsize[i];
}
V_nsize.clear();
LONGLONG comresult;
comresult = netfilesize / m_dirsize * 100;
CString str;
str.Format(_T("%d"),comresult);
str = "%"+str;
AfxMessageBox(_T("下载程度为")+str);
return TRUE;
}
以下为下载文件或者文件夹程序:
有两种做法,第一种,使用类cftpconnection::Getfile 函数进行下载:
使用到的类有:
cinternetsession 、 cftpconnection 、 cftpfilefind 、 CInternetFile 、 vector类
可以根据msdn上的例子进行ftp连接和操作,链接:https://msdn.microsoft.com/zh-cn/library/hf9x9wb4.aspx
下载程序代码如下:
BOOL DownloadFromFTP(CString remotepath,CString localpath,CString ftpaddr,CString username,CString &falreason,CString password,int port)
//定义布尔函数DownloadFromFTP
{
int index = remotepath.ReverseFind('/'); //定义索引本index表示找到与remotepath中最后一个'/'时的值
if (index == -1)
{
falreason = "'/' can't found";
return FALSE; //表示没有找到
}
CString remotefile = remotepath.Mid(index+1,remotepath.GetLength()); //返回'/'后的字符
CInternetSession sess(_T("Download Files Session")); //创建class sess
CFtpConnection* pFtpCon = NULL; //创建class pFtpCon为默认值
BOOL b = 0;
CInternetFile *fTargFile; //计算文件大小时的指针,以下为一些保存的数据定义
vector <LONGLONG> V_nsize;
int outfs;
CString FileSize;
try
{
pFtpCon = sess.GetFtpConnection(ftpaddr,username,password,port); //调用GetFtpConnection连接FTP服务器
if (pFtpCon == NULL) //如果连接失败
{
falreason = "connection is false";
return FALSE; //连接失败时的返回结果
}
CFtpFileFind ftpFinder(pFtpCon); //定义CFtpFileFind对象
BOOL bWorking = ftpFinder.FindFile(remotepath); // 在FTP上查找remotepath(findfile为文件搜索函数,这里应该是查找FTP上有无此路径)
if (bWorking != TRUE) //如果在FTP服务器上没有找到remotepath
{
falreason = remotepath+ "can't found";
return FALSE; //没找到路径时的返回结果
}
CString remotepath1;
/*此处为路径处理,思路为先把remotepath当成文件进行下载,如果失败则当初目录下载*/
if(index == 0 | ig == 0) //如果remotepath直接是文件路径(这里是根目录)那么直接下载,//ig,n都是用来表示当前进入了目录的哪一层
{
remotepath1 = remotepath.Left(index);
}
else
{
index = remotepath.GetLength() - index;
remotepath1=remotepath.Right(index);
}
if(!FolderExists(localpath+remotepath1))
{
CreateMuliteDirectory(localpath+remotepath1); //如果最后一个'/'后面还有文件名,那么此程序会创一个名为此文件名的文件夹
}
b=pFtpCon->GetFile(remotepath, localpath+remotepath1+'/'+remotefile ,TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1);
//GetFile第三项为ture,使得如果目标目录存在此名称的文件,则下载失败返回0导致后面的判断错误
//要问一下是否提示,是否要改为false
if ( !b)
{
while(bWorking) //此循环为下载目录文件的循环
{
bWorking = ftpFinder.FindNextFile();
if (ftpFinder.IsDots()) //如果找到的是"."(表示返回顶级目录)或者".."(表示返回上一级目录)
{
TRACE("%s\n",ftpFinder.GetFileName());
ig --;
continue;
}
else if(ftpFinder.IsDirectory()) //如果找到的是文件夹,递归调用DownloadFromFTP()
{
TRACE("%s\n",ftpFinder.GetFileName());
ig ++ ;
DownloadFromFTP(remotepath+'/'+ftpFinder.GetFileName(),localpath+'/'+remotefile,ftpaddr,username,falreason,password, port);
}
else //如果找到的是文件,直接下载
{
TRACE("%s\n",ftpFinder.GetFileName());
CString remotepath2;
remotepath2 += ftpFinder.GetFileName();
int index1 = remotepath.ReverseFind('/');
if (index1==-1)
{
return false;
}
index1 = remotepath.GetLength() - index1 ;
remotepath2 = remotepath.Right(index1);
if(!FolderExists(localpath+remotepath2))
{
CreateMuliteDirectory(localpath+remotepath2);
}
BOOL c;
c=pFtpCon->GetFile(remotepath+'/'+ftpFinder.GetFileName(), localpath+remotepath2+'/'+ftpFinder.GetFileName(),TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1);
remotepath2.Empty();
/* 下载完成后保存大小*/
if(c)
{
LONGLONG m_filesize = 0;
m_filesize = ftpFinder.GetLength(); //这里使用 cstring保存的时候要考虑cstringa和w的不同
V_nsize.push_back(m_filesize);
}
}
}
/*计算文件夹中文件大小之和*/
LONGLONG m_sumsize = 0;
for(int i=0;i<V_nsize.size();i++)
{
m_sumsize += V_nsize[i];
}
m_dirsize += m_sumsize; //要下载的文件大小之和
CString aa =_T("");
m_sumsize = m_dirsize;
aa.Format( _T("%d"),m_sumsize );
AfxMessageBox(aa);
V_nsize.clear();
}
else //要下载路径直接代表的是文件的情况
{
ij =1;
fTargFile = pFtpCon->OpenFile(remotepath,GENERIC_READ,FTP_TRANSFER_TYPE_BINARY,1 );
__int64 filesize2 = fTargFile->GetLength();
CString aa =_T("");
m_dirsize = filesize2; //储存好了ftp文件大小
aa.Format( _T("%d"),filesize2 );
AfxMessageBox(aa);
fTargFile->Close();
CFile *pFile = NULL;
pFile = new CFile(localpath+remotepath1+'/'+remotefile,CFile::modeRead | CFile::shareDenyNone);
LONGLONG dwLength = pFile->GetLength();
if(m_dirsize == 0 && dwLength == 0)
{
AfxMessageBox(_T("下载文件为空文件"));
}
else
{
LONGLONG comresult;
comresult = m_dirsize / dwLength * 100; //空文件时内存泄露,加了判断后没问题了
CString str;
str.Format(_T("%d"),comresult);
str = "%"+str;
AfxMessageBox(_T("下载程度为")+str);
}
}
}
catch (CInternetException* pEx)
{
TCHAR sz[1024];
pEx->GetErrorMessage(sz, 1024);
falreason = sz;
printf("%s",sz);
pEx->Delete();
}
if (pFtpCon != NULL)
{
pFtpCon->Close();
delete pFtpCon;
pFtpCon = NULL;
}
return TRUE;
}
第二种:使用读写函数,可以直接在下载的时候就保存文件大小,故不需要使用自写的那个LocalFileCompa函数
BOOL DownloadFromFTP(CString remotepath,CString localpath,CString ftpaddr,CString username,CString &falreason,CString password,int port) //定义布尔函数DownloadFromFTP
{
int index = remotepath.ReverseFind('/'); //定义索引本index表示找到与remotepath中最后一个'/'时的
if (index == -1)
{
falreason = "'/' can't found";
return FALSE; //表示没有找到
}
CString remotefile = remotepath.Mid(index+1,remotepath.GetLength()); //返回'/'后的字符
CInternetSession sess(_T("Download Files Session")); //创建class sess
CFtpConnection* pFtpCon = NULL; //创建class pFtpCon为默认值
BOOL b = 0;
CInternetFile *fTargFile;
vector <LONGLONG> V_nsize;
vector <LONGLONG> V_fsize;
CString FileSize;
//以下加入断点续传的变量定义
unsigned char filebuf[512];
LONGLONG outfs;
CString KBin,Perc;
try
{
pFtpCon = sess.GetFtpConnection(ftpaddr,username,password,port); //调用GetFtpConnection连接FTP服务器
if (pFtpCon == NULL) //如果连接失败
{
falreason = "connection is false";
return FALSE; //连接失败时的返回结果
}
CFtpFileFind ftpFinder(pFtpCon); //定义CFtpFileFind对象
CString str_path(remotepath);
str_path += (_T("\\*.*")); //意思是当前目录下以“任意文件名,任意扩展名”命名的文件
BOOL bWorking = ftpFinder.FindFile(str_path); // 在FTP上查找remotepath(findfile为文件搜索函数,这里应该是查找FTP上有无此路径)
if (bWorking != TRUE) //如果在FTP服务器上没有找到remotepath
{
falreason = remotepath+ "can't found";
return FALSE; //没找到路径时的返回结果
}
while(bWorking) //此循环为下载目录文件的循环
{
bWorking = ftpFinder.FindNextFile();
if (ftpFinder.IsDots()) //如果找到的是"."(表示返回顶级目录)或者".."(表示返回上一级目录)
{
TRACE("%s\n",ftpFinder.GetFileName());
ig --;
continue;
}
else if(ftpFinder.IsDirectory()) //如果找到的是文件夹,递归调用DownloadFromFTP()
{
TRACE("%s\n",ftpFinder.GetFileName());
ig ++ ;
DownloadFromFTP(remotepath+'/'+ftpFinder.GetFileName(),localpath+'/'+remotefile,ftpaddr,username,falreason,password, port);
}
else //如果找到的是文件,直接下载 /223.jpg /220/223.jpg /521/522/223/1.jpg /220 4种情况
{
CString openpath ; //这种遍历的改写会导致判断文件与文件夹出错
CString remotepath2; //本地目录创建路径
CString openlocpath; //本地将要写的文件路径
/*以下为路径的拼接,可在调试的时候细看*/
if(remotefile == ftpFinder.GetFileName())//此判断主要用于/223.jpg和/220的区别
{
openpath = remotepath;
int index1 = openpath.ReverseFind('/');
if (index1==-1)
{
return false;
}
else
{
remotepath2 = openpath.Left(index);
openlocpath = localpath + remotepath;
}
}
else if(ig == 0) //根目录文件情况
{
openpath = remotepath + '/'+ ftpFinder.GetFileName();
remotepath2 = remotepath;
openlocpath = localpath + openpath;
}
else
{
openpath = remotepath + '/' + ftpFinder.GetFileName();
remotepath2 = '/'+ remotefile ;
openlocpath = localpath + '/'+remotefile+'/'+ftpFinder.GetFileName();
}
LONGLONG filesize = ftpFinder.GetLength(); //计算要下载的ftp文件大小
outfs = filesize / 1024;
if(filesize == 0) //此处的文件计算改为网络连接
{
falreason = "文件大小为0";
return FALSE;
}
V_fsize.push_back(outfs);
FileSize.Format("%d",outfs);
fTargFile = pFtpCon->OpenFile(openpath,GENERIC_READ,FTP_TRANSFER_TYPE_BINARY,1 );//getlength必须放在openfile之前才可行
/* 添加openfile错误时的处理代码 */
nDownloaded = 1;
if(FolderExists(localpath+remotepath2) == FALSE) //调用函数创建目录
{
CreateMuliteDirectory(localpath+remotepath2);
}
CFile fDestFile;
BOOL k;
k = fDestFile.Open(openlocpath,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
//打开目标必须是文件,不然后面的读和写都会错误
if(k == 0)
{
return FALSE;
}
LONGLONG byteswrite = 0 ; //保存写入大小
LONGLONG pos = 0 ; //保存已写入数据
LONGLONG nperc, kbrecv;
//百分比 ,已收到数据 ,此百分比只表示当前下载的文件,如果是文件夹,那么会分别显示每一项文件下载的百分比
//与之类似,文件夹时会显示每一项文件的大小
while(byteswrite = fTargFile->Read(filebuf,512))
{
pos = pos + byteswrite;
fDestFile.Write(filebuf, byteswrite); //..上面的open问题,,改成功
nperc = pos * 100 / filesize;
kbrecv = pos / 1024;
Perc.Format("%d",nperc); // 格式化进度百分比
KBin.Format("%d",kbrecv); // 格式化已下载数据大小(KB)
//AfxMessageBox(Perc);
// AfxMessageBox(KBin);
}
// AfxMessageBox(Perc);
// AfxMessageBox(KBin);
V_nsize.push_back(kbrecv);
fDestFile.Close();
TRACE("%s\n",ftpFinder.GetFileName());
}
}
LONGLONG m_sumsize = 0;
LONGLONG m_fsumsize = 0 ;
for(int i=0;i<V_nsize.size();i++)
{
m_sumsize += V_nsize[i];
}
for (int j=0;j<V_fsize.size();j++)
{
m_fsumsize += V_fsize[j];
}
m_dirsize += m_sumsize ;
m_fdirsize += m_fsumsize;
V_nsize.clear();
V_fsize.clear();
}
catch (CInternetException* pEx)
{
TCHAR sz[1024];
pEx->GetErrorMessage(sz, 1024);
falreason = sz;
printf("%s",sz);
pEx->Delete();
}
if (pFtpCon != NULL)
{
pFtpCon->Close();
delete pFtpCon;
pFtpCon = NULL;
}
return TRUE;
}
按钮函数、控件函数 放在下面
void CobjplayerDlg::OnBnClickedconnectButton()
{
// TODO: Add your control notification handler code here
m_string.clear();
m_dotstring.clear();
m_ftppath=(_T(""));
m_listBox.ResetContent();
V_counterpart.clear();
n=0;
UpdateData(TRUE);
FtpList(m_ftppath,(m_ftpadress),(m_username),m_Freason,(m_password),m_port);
UpdateData(FALSE);
size[n]=m_string.size();
for(unsigned int i=0;i<m_string.size();i++) //显示根目录 0层
{
m_listBox.AddString(m_string.at(i));
}
if (m_dotstring.size()!=0)
{
for(unsigned int j=0;j<m_dotstring.size();j++)
{
m_listBox.AddString(m_dotstring.at(j));
}
}
}
void CobjplayerDlg::OnBnClickedshownextdirButton()
{
// TODO: Add your control notification handler code here
CString n_ftppath;
int NcurSel;
NcurSel = m_listBox.GetCurSel();
if(m_listBox.GetCount()!=0) //判断是否为空目录,果然为空目录就不执行循环
{
if(NcurSel!=-1) //加一个判断,如果未选择列表项则不执行程序并弹出提示框, 未选择时不为1
{
if(NcurSel<size[n]) //加一个判断,如果是文件则报错,不执行下面创建副本以及进入下一层目录操作
{
if(n+1) //按下显示下一层按钮时创建副本存储当前层数据
{
vector <CString> V_n; //创建临时副本V_n
CString strText;
int numlist;
numlist= m_listBox.GetCount(); //当前列表项数量
for(int k=0;k<numlist;k++)
{
m_listBox.GetText(k,strText);
V_n.push_back(strText); //把当前的列表信息保存在当临时副本,数据数量为numlist
}
for(int l=0;l<numlist;l++)
{
V_counterpart.push_back(V_n[l]) ; //当前副本信息转移到公共副本
}
dir[n]=numlist; //当前目录包含文件数,记录此层存放在公共副本的数据数dir【0】=4 dir【1】=3
//第0层为"" 第一层为/521
numlist=m_listBox.GetCurSel();
m_listBox.GetText(numlist,strText);
V_ftppath.push_back("/"+strText);
V_n.clear(); //清除临时副本
n++; //当前层数
}
m_string.clear(); //此处开始为进入下一层目录的代码
m_dotstring.clear();
m_listBox.GetText(NcurSel, n_ftppath);
m_ftppath=m_ftppath+L"/"+n_ftppath; //"/520"
m_listBox.ResetContent();
UpdateData(TRUE);
FtpList(m_ftppath,(m_ftpadress),(m_username),m_Freason,(m_password),m_port);
UpdateData(FALSE);
size[n]=m_string.size();
for(unsigned int i=0;i<m_string.size();i++)
{
m_listBox.AddString(m_string.at(i));
}
if (m_dotstring.size()!=0)
{
for(unsigned int j=0;j<m_dotstring.size();j++)
{
m_listBox.AddString(m_dotstring.at(j));
}
}
}
else
{
INT_PTR nRes; // 用于保存DoModal函数的返回值
CTipDlg tipDlg; // 构造对话框类CTipDlg的实例
nRes = tipDlg.DoModal(); // 弹出对话框
if (IDCANCEL == nRes) // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行
return;
m_listBox.GetText(NcurSel, n_ftppath);
m_ftppath=m_ftppath+L"/"+n_ftppath;
UpdateData(TRUE);
DownloadFromFTP(m_ftppath,(m_localpath),(m_ftpadress),(m_username),m_Freason,(m_password),m_port);
UpdateData(FALSE);
}
}
else
{
CString m_false;
m_false="请选择列表项";
AfxMessageBox(m_false);
}
}
else
{
CString n_false;
n_false="空目录,无法进入下一层";
AfxMessageBox(n_false);
}
}
void CobjplayerDlg::OnBnClickedReturnButton()
{
// TODO: Add your control notification handler code here
if(n>0) //n现在是2
{
m_string.clear();
m_dotstring.clear();
m_listBox.ResetContent(); //先清除当前列表数据
int l=0;
for(int j=0;j<n-1;j++) //除了返回层以外的其他数据数量
{
l=l+dir[j];
}//需要显示第1层数据,即后面3个数据,V_counterpart[4] [5] [6] dir[0]=4 dir [1]=3 V_counterpart.size()=7 循环为
for(unsigned int i=l;i<V_counterpart.size();i++) //根据N显示哪一个副本
{
m_listBox.AddString(V_counterpart.at(i)); //根据条件显示副本中数据
}
V_counterpart.resize(l);
m_ftppath.TrimRight(V_ftppath[n-1]);
V_ftppath.resize(n-1); //在公共副本中清除当前显示数据层以及之后层的数据
dir[n-1]=0;
size[n]=0;
n--; //返回处理之后层数,逻辑为显示下一层n+1,返回上一层n-1
}
else
{
CString d_false;
d_false="已到达顶层";
AfxMessageBox(d_false);
}
}
void CobjplayerDlg::OnBnClickeddownloadButton()
{
// TODO: Add your control notification handler code here
CString n_ftppath;
int NcurSel;
NcurSel = m_listBox.GetCurSel();
if(m_listBox.GetCount()!=0) //判断是否为空目录,果然为空目录就不执行循环
{
if(NcurSel!=-1) //加一个判断,如果未选择列表项则不执行程序并弹出提示框, 未选择时不为1
{
m_listBox.GetText(NcurSel, n_ftppath);
CString c_remotepath = m_ftppath;
CString c_remotepath1 = m_ftppath;
UpdateData(TRUE);
m_ftppath=c_remotepath+L"/"+n_ftppath;
DownloadFromFTP(m_ftppath,(m_localpath),(m_ftpadress),(m_username),m_Freason,(m_password),m_port);
if (ij == 0)
{
LocalFileCompa(m_localpath+m_ftppath,m_dirsize);
}
m_ftppath = c_remotepath;
UpdateData(FALSE);
}
else
{
CString m_false;
m_false="请选择列表项";
AfxMessageBox(m_false);
}
}
else
{
CString n_false;
n_false="空目录,无法下载";
AfxMessageBox(n_false);
}
}
void CobjplayerDlg::OnDblclkDirshowList1()
{
// TODO: Add your control notification handler code here
CString n_ftppath;
int NcurSel;
NcurSel = m_listBox.GetCurSel();
if(m_listBox.GetCount()!=0) //判断是否为空目录,果然为空目录就不执行循环
{
if(NcurSel!=-1) //加一个判断,如果未选择列表项则不执行程序并弹出提示框, 未选择时不为1
{
if(NcurSel<size[n]) //加一个判断,如果是文件则报错,不执行下面创建副本以及进入下一层目录操作
{
if(n+1) //按下显示下一层按钮时创建副本存储当前层数据
{
vector <CString> V_n; //创建临时副本V_n
CString strText;
int numlist;
numlist= m_listBox.GetCount(); //当前列表项数量
for(int k=0;k<numlist;k++)
{
m_listBox.GetText(k,strText);
V_n.push_back(strText); //把当前的列表信息保存在当临时副本,数据数量为numlist
}
for(int l=0;l<numlist;l++)
{
V_counterpart.push_back(V_n[l]) ; //当前副本信息转移到公共副本
}
dir[n]=numlist; //当前目录包含文件数,记录此层存放在公共副本的数据数dir【0】=4 dir【1】=3
//第0层为"" 第一层为/521
numlist=m_listBox.GetCurSel();
m_listBox.GetText(numlist,strText);
V_ftppath.push_back("/"+strText);
V_n.clear(); //清除临时副本
n++; //当前层数
}
m_string.clear(); //此处开始为进入下一层目录的代码
m_dotstring.clear();
m_listBox.GetText(NcurSel, n_ftppath);
m_ftppath=m_ftppath+L"/"+n_ftppath; //"/520"
m_listBox.ResetContent();
UpdateData(TRUE);
FtpList(m_ftppath,(m_ftpadress),(m_username),m_Freason,(m_password),m_port);
UpdateData(FALSE);
size[n]=m_string.size();
for(unsigned int i=0;i<m_string.size();i++)
{
m_listBox.AddString(m_string.at(i));
}
if (m_dotstring.size()!=0)
{
for(unsigned int j=0;j<m_dotstring.size();j++)
{
m_listBox.AddString(m_dotstring.at(j));
}
}
}
else
{
INT_PTR nRes; // 用于保存DoModal函数的返回值
CTipDlg tipDlg; // 构造对话框类CTipDlg的实例
nRes = tipDlg.DoModal(); // 弹出对话框
if (IDCANCEL == nRes) // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行
return;
m_listBox.GetText(NcurSel, n_ftppath);
m_ftppath=m_ftppath+L"/"+n_ftppath;
UpdateData(TRUE);
DownloadFromFTP(m_ftppath,(m_localpath),(m_ftpadress),(m_username),m_Freason,(m_password),m_port);
UpdateData(FALSE);
}
}
else
{
CString m_false;
m_false="请选择列表项";
AfxMessageBox(m_false);
}
}
else
{
CString n_false;
n_false="空目录,无法进入下一层";
AfxMessageBox(n_false);
}
}
- 使用MFC对FTP文件或者文件夹进行下载、断点续传等功能的个人理解
- 使用sftp对文件进行上传或者是下载
- FTP文件下载与断点续传
- FTP 文件的下载功能
- mfc ftp文件下载
- 利用Apache commons-net 包进行FTP文件和文件夹的上传与下载
- 关于Qt使用QNetworkAccessManager下载文件(实现断点续传功能)
- 关于Qt使用QNetworkAccessManager下载文件(实现断点续传功能)
- ftp Client递归下载ftp上某个文件夹的文件
- RxJava打造的下载工具, 支持多线程下载和断点续传, 智能判断是否支持断点续传等功能
- 《FTP、HTTP 多线程断点续传下载文件》 FlashGet
- 用FTPClient对ftp文件进行上传下载等操作
- Firefox自带下载功能进行断点续传
- 断点续传的方式进行下载
- 断点续传的方式进行下载
- 实现断点续传功能的下载
- 实现断点续传功能的下载
- 对文件或文件夹进行 增删改查等操作的工具类
- css3 属性 transition
- 在python2.7.X中怎么安装numpy scipymatplotlib pandas等模块
- JavaScript qq窗口抖动效果
- css 实现的简单的图片…
- centos mariadb galera 多主同步 haprox keepalive 集群热备
- 使用MFC对FTP文件或者文件夹进行下载、断点续传等功能的个人理解
- JavaScript 之 onkeydown 事件
- $on、$emit和$broadcast的使用
- css3 的艰难
- html submit 与 button 是不同的
- 机器学习之梯度下降算法
- 数据结构初学之----线性结构,树型…
- html+css 之 文本框透明…
- SQL查询封装到对象