新手入门,借鉴了很多地方写的
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 dir[20]; //创建一个可以保存20个数的数组来保存目录存储时每一层有多少个文件和目录,现在可以存储10层目录,控制这个数组大小可以控制目录的层数
int size[20]; //存储每层多少目录
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;
}
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;
}
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;
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+ L"can't found";
return FALSE; //没找到路径时的返回结果
}
CString remotepath1=remotepath.Left(index+1);
;//如果最后一个'/'后面还有文件名,那么此程序会创一个名为此文件名的文件夹
if(!FolderExists(localpath+'/'+remotepath1))
{
CreateMuliteDirectory(localpath+'/'+remotepath1);
}
b=pFtpCon->GetFile(remotepath, localpath+'/'+remotepath1+'/'+remotefile ,TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1);
if ( !b)
{
while(bWorking) //此循环为下载目录文件的循环
{
bWorking = ftpFinder.FindNextFile();
if (ftpFinder.IsDots()) //如果找到的是"."(表示返回顶级目录)或者".."(表示返回上一级目录)
{
TRACE("%s\n",ftpFinder.GetFileName());
continue;
}
else if(ftpFinder.IsDirectory()) //如果找到的是文件夹,递归调用DownloadFromFTP()
{
TRACE("%s\n",ftpFinder.GetFileName());
DownloadFromFTP(remotepath+'/'+ftpFinder.GetFileName(),localpath+'/'+remotefile,ftpaddr,username,falreason,password, port);
}
else //如果找到的是文件,直接下载
{
TRACE("%s\n",ftpFinder.GetFileName());
if(!FolderExists(localpath+'/'+remotepath))
{
CreateMuliteDirectory(localpath+'/'+remotepath);
}
pFtpCon->GetFile(remotepath+'/'+ftpFinder.GetFileName(), localpath+'/'+remotepath+'/'+ftpFinder.GetFileName(),TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1);
}
}
}
}
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 CftpDLDlg::OnBnClickedconnectButton1()
{
// 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,(_T("192.168.1.161")),(_T("admin")),m_Freason,(_T("admin")),74);
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 CftpDLDlg::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(L"/"+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();
FtpList(m_ftppath,(_T("192.168.1.161")),(_T("admin")),m_Freason,(_T("admin")),74);
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
{
CString d_false;
d_false="选择项为文件,无法进入下一层";
AfxMessageBox(d_false);
}
}
else
{
CString m_false;
m_false="请选择列表项";
AfxMessageBox(m_false);
}
}
else
{
CString n_false;
n_false="空目录,无法进入下一层";
AfxMessageBox(n_false);
}
}
void CftpDLDlg::OnBnClickedReturnButton2()
{
// 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
}
void CftpDLDlg::OnLbnSelchangedirshowList1() //此函数还要加一些点击什么的功能
{
// TODO: Add your control notification handler code here
CString strText;
int nCurSel;
nCurSel = m_listBox.GetCurSel(); // 获取当前选中列表项
m_listBox.GetText(nCurSel, strText); // 获取选中列表项的字符串
}
void CftpDLDlg::OnBnClickeddownloadButton2()
{
// 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);
m_ftppath=m_ftppath+L"/"+n_ftppath;
DownloadFromFTP(m_ftppath,(_T("D:/ftp")),(_T("192.168.1.161")),(_T("admin")),m_Freason,(_T("admin")),74);
UpdateData(FALSE);
}
else
{
CString m_false;
m_false="请选择列表项";
AfxMessageBox(m_false);
}
}
else
{
CString n_false;
n_false="空目录,无法下载";
AfxMessageBox(n_false);
}
}