使用MFC对FTP文件或者文件夹进行下载、断点续传等功能的个人理解

函数功能: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)
{

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值