FTP下载类, windows平台下对CFtpConnection上传下载的封装类

以前一直没找到CFtpConnection的简单封装类,所以今天自己写了一个,供有需要的朋友使用

 

该类只是简单的封装,不可能达到socket来实现FTP功能的灵活和性能。

你也可以自己改造,如类里加入线程启动下载,加入上传下载通知消息等,因为我用不上,所以就不加了

使用HTTP上传下载的方法也类似,可以做为参考

 

使用说明:

 

 

CMyFtp ftpTest("192.168.16.63", "test", "test112", 21);

 

bool result = ftpTest.UploadFile("336.txt","d://111.txt");

if(!result)

AfxMessageBox(ftpTest.GetErrorMsg());

 

ftpTest.DownloadFile( "336.txt", "12.txt");

 

ftpTest.CreateRemoteDirectory("test222");

 

ftpTest.SetRemoteDir("test222");

 

ftpTest.UploadFile("113.txt","d://111.txt");

 

ftpTest.SetRemoteDir("//");

 

ftpTest.UploadFile("116.txt","d://111.txt");

 

 

.h文件

// MyFtpClient.h: interface for the CMyFtpClient class.
//
//

#include <afxinet.h>


#if !defined(AFX_MYFTPCLIENT_H__A9FC4CC7_20CE_4700_B93F_8381A3E3F5C5__INCLUDED_)
#define AFX_MYFTPCLIENT_H__A9FC4CC7_20CE_4700_B93F_8381A3E3F5C5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CMyFtpClient  
{
public:
	CMyFtpClient();
	CMyFtpClient(CString str_ip, CString str_user, CString str_pwd, UINT port);
	virtual ~CMyFtpClient();

	void setParm(CString str_ip, CString str_user, CString str_pwd, UINT port);
	void setPassive(BOOL state){ m_passive = state;}//设定FTP Passive

	static bool login();//登录
	bool logout();//退出

	//上传文件
	static DWORD WINAPI UploadFile(LPVOID lpParameter);
	bool UploadFileThread(CString str_remoteFileName/*远程文件名,必须是当前路径下的文件*/,
		CString str_LocalFileName/*本地文件名,全路径*/);

	//上传文件列表,参数参考 UploadFile
	bool UploadFileList(CStringList str_remoteFileNameList, CStringList str_LocalFileList);//上传

	//设置远程当前路径
	bool SetRemoteDir(CString str_remoteDir);

	//设置远程当前路径为根目录
	bool SetRemoteRoot(){ return SetRemoteDir(_T("/"));}

	//得到远程当前路径
	CString GetRemoteDir(){  
		m_pConnect->GetCurrentDirectory(m_remoteCurrentDir); 
		return m_remoteCurrentDir; }

	//创建远程目录,不会改变当前远程路径
	bool CreateRemoteDir(CString str_dirName);

	//删除远程目录及目录下的子文件,子文件夹
	bool DelRemoteDir(CString str_dirName);

	//删除远程文件
	bool DelRemoteFile(CString str_FileName);

	//重命名远程文件
	bool RenameRemoteFile(CString str_OldFileName,CString str_NewFileName);


	//下载远程文件
	bool DownloadFile(CString str_remoteFileName/*远程文件名*/, CString str_LocalFileName/*本地文件名*/);

	//下载远程文件列表
	bool DownloadFileList(CStringList str_remoteFileNameList, CStringList str_LocalFileList);

	//得到错误信息
	CString GetErrorMsg();

	//上传进度百分比
	DWORD GetUploadFilePercent();

	//上传速度 bytes/s
	DWORD  GetUploadSpeed();

	//下载进度百分比
	DWORD GetDownloadFilePercent();

	//下载速度 bytes/s
	DWORD  GetDownloadSpeed();

	//设定文件每次读写大小,网速越快,值设置越大
	void SetFileStepSize(DWORD dSize){ m_FileLenStep = dSize*1024; }

	// 取得目录下的所有文件
	void GetFileInPath(LPCTSTR lpszPath, CStringArray &arrstrFile, 
		BOOL bFindSubDir/* = FALSE*/,
		LPCTSTR lpszFileExt);

private:
	static BOOL m_passive;
	static CString m_errorMsg;
	static BOOL m_bLogin;
	CString m_remoteCurrentDir;

	static CFile m_CFile;


	static CInternetSession m_session;
	static CFtpConnection * m_pConnect;
	static CInternetFile * m_pRemoteFile;

	static CString m_Ip,m_user,m_pwd;
	static UINT m_port;
	static DWORD m_FileLenStep;

	static DWORD m_TotalUploadSize, m_TotalDownloadSize;
	static DWORD m_CurUploadSize, m_CurDownloadSize;

	DWORD m_UploadSpeed, m_DownloadSpeed;

	void Init();
	static void CloseRemoteFile();
	static void SetErrorMsg();

	static CString m_str_remoteFileName, m_str_LocalFileName;
};

#endif // !defined(AFX_MYFTP_H__A9FC4CC7_20CE_4700_B93F_8381A3E3F5C5__INCLUDED_)

 

.cpp文件

// MyFtpClient.cpp: implementation of the CMyFtpClient class.
//
//

#include "stdafx.h"
#include "MyFtpClient.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//
DWORD CMyFtpClient::m_TotalUploadSize = 0, CMyFtpClient::m_TotalDownloadSize = 0;
DWORD CMyFtpClient::m_CurUploadSize = 0, CMyFtpClient::m_CurDownloadSize = 0;
DWORD CMyFtpClient::m_FileLenStep = 1024*1024;


CFtpConnection * CMyFtpClient::m_pConnect = NULL;
CInternetFile * CMyFtpClient::m_pRemoteFile = NULL;
CInternetSession CMyFtpClient::m_session;

CFile CMyFtpClient::m_CFile;

CString CMyFtpClient::m_str_remoteFileName = "", CMyFtpClient::m_str_LocalFileName = "";
CString CMyFtpClient::m_errorMsg = "";
CString CMyFtpClient::m_Ip = "", CMyFtpClient::m_user = "", CMyFtpClient::m_pwd = "";
BOOL CMyFtpClient::m_passive = FALSE;
BOOL CMyFtpClient::m_bLogin = FALSE;
UINT CMyFtpClient::m_port = 20;


CMyFtpClient::CMyFtpClient()
{
	Init();
}

CMyFtpClient::~CMyFtpClient()
{
	logout();
}

CMyFtpClient::CMyFtpClient(CString str_ip, CString str_user, CString str_pwd, UINT port)
{
	m_Ip = str_ip;
	m_user = str_user;
	m_pwd = str_pwd;
	m_port = port;

	Init();
}

void CMyFtpClient::Init()
{
	m_pConnect = NULL;
	m_pRemoteFile = NULL;
	m_FileLenStep = 1024*1024;


	m_CurUploadSize = m_TotalUploadSize = m_CurDownloadSize = m_TotalDownloadSize = 0;

	setPassive(FALSE);
}

void CMyFtpClient::setParm(CString str_ip, CString str_user, CString str_pwd, UINT port)
{

	m_Ip = str_ip;
	m_user = str_user;
	m_pwd = str_pwd;
	m_port = port;

}

bool CMyFtpClient::login()
{


	try
	{

		if(m_bLogin)
			return true;


		//m_pConnect = m_session.GetFtpConnection( m_Ip, m_user,
			//m_pwd, m_port, m_passive);
		m_pConnect = m_session.GetFtpConnection( m_Ip, m_user,
			m_pwd, m_port, m_passive);
		if(m_pConnect == NULL)
		{
			SetErrorMsg();
			return false;
		}
	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
		delete m_pConnect;
		m_pConnect = NULL;
		m_session.Close();
		return false;
	}
	catch (...)
	{
		SetErrorMsg();
		delete m_pConnect;
		m_pConnect = NULL;
		m_session.Close();
		return false;
	}

	m_bLogin = TRUE;
	return true;

}
bool CMyFtpClient::logout()
{
	try
	{
		if(m_pRemoteFile)
		{
			m_pRemoteFile->Close();
			delete m_pRemoteFile;
			m_pRemoteFile = NULL;
		}

		if(m_pConnect)
		{
			m_pConnect->Close();
			delete m_pConnect;
			m_pConnect = NULL;
		}

		m_bLogin = FALSE;

		//m_session.Close();

	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
		delete m_pRemoteFile;
		m_pRemoteFile = NULL;
		delete m_pConnect;
		m_pConnect = NULL;
		m_bLogin = FALSE;
		return false;
	}
	catch (...)
	{
		SetErrorMsg();
		return false;
	}



	m_bLogin = FALSE;
	return true;
}

void CMyFtpClient::CloseRemoteFile()
{
	try
	{
		if(m_pRemoteFile)
		{
			m_pRemoteFile->Close();
			delete m_pRemoteFile;
			m_pRemoteFile = NULL;
		}
	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
	}
	catch (...)
	{
		SetErrorMsg();
	}


}

bool CMyFtpClient::UploadFileThread(CString str_remoteFileName, CString str_LocalFileName)
{

	DWORD      _i;

	m_str_remoteFileName = str_remoteFileName;
	m_str_LocalFileName = str_LocalFileName;

	m_CurUploadSize = m_TotalUploadSize = m_CurDownloadSize = m_TotalDownloadSize = 0;

	::CreateThread (NULL, 0, UploadFile, this, 0,&_i);

	return 1;
}

DWORD CMyFtpClient::UploadFile(LPVOID lpParameter)
{


	BOOL bOpen = FALSE;

	char *pBuf = NULL;


	try
	{
		if(m_pConnect == NULL)
		{
			if ( !login() )
			{
				return false;
			}
		}

		m_pRemoteFile =  m_pConnect->OpenFile(m_str_remoteFileName, GENERIC_WRITE);
		if(m_pRemoteFile == NULL)
		{
			AfxMessageBox(m_str_remoteFileName + "  :远程文件创建失败");
			return false;
		}


		bOpen = m_CFile.Open( m_str_LocalFileName , CFile::modeRead );
		if(!bOpen)
		{
			AfxMessageBox(m_str_LocalFileName + "  :本地文件打开失败");
			return false;
		}

		m_TotalUploadSize =  m_CFile.GetLength();


		m_FileLenStep = m_FileLenStep > m_TotalUploadSize ? m_TotalUploadSize : m_FileLenStep;

		DWORD dwRead = m_FileLenStep;

		pBuf = new char[m_FileLenStep+1];
		memset(pBuf, 0x00, m_FileLenStep+1);

		while( (dwRead = m_CFile.Read(pBuf, m_FileLenStep)) > 0 )
		{
			m_pRemoteFile->Write( pBuf, dwRead );

			m_CurUploadSize += dwRead;
		}

		delete pBuf;		
		m_CFile.Close();

	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();

		delete pBuf;
		if(bOpen)
			m_CFile.Close();
		return false;
	}
	catch (...)
	{
		SetErrorMsg();
		delete pBuf;
		if(bOpen)
			m_CFile.Close();

		return false;
	}

	CloseRemoteFile();

	return true;


}
bool CMyFtpClient::UploadFileList(CStringList str_remoteFileNameList, CStringList str_LocalFileList)
{
	for(int i = 0; i< str_remoteFileNameList.GetCount(); i++)
	{
		CString remoteFile = str_remoteFileNameList.GetAt(str_remoteFileNameList.FindIndex(i));
		CString localFile = str_LocalFileList.GetAt(str_LocalFileList.FindIndex(i));

		UploadFileThread( remoteFile, localFile );
	}

	return true;
}
bool CMyFtpClient::CreateRemoteDir(CString str_dirName)
{
	try
	{
		if(m_pConnect == NULL)
			return false;

		if ( m_pConnect->CreateDirectory(str_dirName) <= 0 )
			return false;

		return SetRemoteDir(str_dirName);


	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
		return false;
	}
	catch (...)
	{
		SetErrorMsg();
		return false;
	}



	return true;
}

bool CMyFtpClient::SetRemoteDir(CString str_remoteDir)
{ 
	try
	{
		if(m_pConnect == NULL)
			return false;


		if( m_pConnect->SetCurrentDirectory( str_remoteDir) <= 0 )
				return false;

		m_pConnect->GetCurrentDirectory(m_remoteCurrentDir);


	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
		return false;
	}
	catch (...)
	{
		SetErrorMsg();
		return false;
	}

	return true;

}

bool CMyFtpClient::DelRemoteDir(CString str_remoteDir/*全路径或当前路径下的文件夹*/)
{ 

_RECALL:
	CFtpFileFind ftpFind(m_pConnect);


	try
	{
		if(m_pConnect == NULL)
			return false;

		if(str_remoteDir.Left(1) != "/")//不是全路径
		{
			CString strPath;
			m_pConnect->GetCurrentDirectory(strPath);
			str_remoteDir = strPath + _T("/") + str_remoteDir + _T("/*");
		}

		SetRemoteDir(str_remoteDir);




		BOOL bContinue = ftpFind.FindFile(str_remoteDir);


		if (!bContinue)//是个空目录,删除
		{
			SetRemoteDir("..");//返回上层
			m_pConnect->RemoveDirectory(str_remoteDir);//删除
			goto _QUIT;
		}



		bContinue = ftpFind.FindFile();
		if (!bContinue)//文件未找到
		{
			goto _QUIT;
		}


		do 
		{
			bContinue =  ftpFind.FindNextFile();

			if (ftpFind.IsDirectory())
			{
				CString strPath = ftpFind.GetFilePath();
				ftpFind.Close();

				DelRemoteDir( strPath );//递归调用
				SetRemoteDir("..");//返回上层
				goto _RECALL;
			}
			else
			{				
				DelRemoteFile(ftpFind.GetFileName());
			}
		}
		while (bContinue);


	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
		goto _FAIL;
	}
	catch (...)
	{
		SetErrorMsg();
		goto _FAIL;
	}


_QUIT:
	ftpFind.Close();
	return true;

_FAIL:

	ftpFind.Close();
	return false;
}

bool CMyFtpClient::DelRemoteFile(CString str_FileName)
{ 
	try
	{
		if(m_pConnect == NULL)
			return false;

		if( m_pConnect->Remove( str_FileName ) <= 0 )
			return false;


	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
		return false;
	}
	catch (...)
	{
		SetErrorMsg();
		return false;
	}

	return true;

}

bool CMyFtpClient::RenameRemoteFile(CString str_OldFileName,CString str_NewFileName)
{ 
	try
	{
		if(m_pConnect == NULL)
			return false;

		if( m_pConnect->Rename( str_OldFileName,  str_NewFileName ) <= 0 )
			return false;


	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();
		return false;
	}
	catch (...)
	{
		SetErrorMsg();
		return false;
	}

	return true;

}

bool CMyFtpClient::DownloadFile(CString str_remoteFileName, CString str_LocalFileName)
{
	LPBYTE pBuffer = new BYTE[m_FileLenStep+1];
	memset(pBuffer, 0, m_FileLenStep+1);

	CFile wrireFile;

	try
	{
		if(m_pConnect == NULL)
		{
			if ( !login() )
			{
				return false;
			}
		}

		if( !wrireFile.Open(str_LocalFileName, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary))
		{
			AfxMessageBox(str_LocalFileName + "  :文件创建失败");

			CloseRemoteFile();
			return false;
		}


		m_pRemoteFile =  m_pConnect->OpenFile(str_remoteFileName, GENERIC_READ);
		if(m_pRemoteFile == NULL)
		{
			AfxMessageBox(str_remoteFileName + "  :远程文件打开失败");
			return false;
		}





		m_TotalDownloadSize = m_pRemoteFile->GetLength();//远程文件总长度

		m_FileLenStep = m_FileLenStep > m_TotalDownloadSize ? m_TotalDownloadSize : m_FileLenStep;



		DWORD dRead = 0;
		while( (dRead = m_pRemoteFile->Read( pBuffer, m_FileLenStep)) > 0  ) 
		{
			wrireFile.Write( pBuffer, dRead );

			m_CurDownloadSize += dRead;
		}

		wrireFile.Close();


	}
	catch(CInternetException *pEx)
	{
		pEx->GetErrorMessage( m_errorMsg.GetBuffer(0), 1024 );
		pEx->Delete();

		wrireFile.Close();
		return false;
	}
	catch (...)
	{
		SetErrorMsg();

		wrireFile.Close();
		return false;
	}




	delete pBuffer;
	CloseRemoteFile();


	return true;





}
bool CMyFtpClient::DownloadFileList(CStringList str_remoteFileNameList, CStringList str_LocalFileList)
{
	for(int i = 0; i< str_remoteFileNameList.GetCount(); i++)
	{
		CString remoteFile = str_remoteFileNameList.GetAt(str_remoteFileNameList.FindIndex(i));
		CString localFile = str_LocalFileList.GetAt(str_LocalFileList.FindIndex(i));

		DownloadFile( remoteFile, localFile );
	}

	return true;
}

DWORD CMyFtpClient::GetUploadFilePercent()
{
	if(m_TotalUploadSize <=0)
		return 0;


	double d1,d2,d3;
	d2 = m_CurUploadSize;
	d3 = m_TotalUploadSize;
	d1 = d2  / d3;

	return d1 * 100 ;	
}

DWORD CMyFtpClient::GetDownloadFilePercent()
{
	return m_CurDownloadSize * 100 / m_TotalDownloadSize;
}

CString CMyFtpClient::GetErrorMsg()
{
	return "";
	return m_errorMsg;
}

void CMyFtpClient::SetErrorMsg()
{
	return;

	LPVOID lpMsgBuf; 
	FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
		FORMAT_MESSAGE_FROM_SYSTEM | 
		FORMAT_MESSAGE_IGNORE_INSERTS, 
		NULL, 
		GetLastError(), 
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 
		(LPTSTR) &lpMsgBuf, 
		0, 
		NULL 
		); 

	m_errorMsg.Format("%s",lpMsgBuf);

	LocalFree(   lpMsgBuf   );
}


// 判断路径是否存在
BOOL IsPathExist(LPCTSTR lpszPathName)
{
	CString strTemp;
	if(GetCurrentDirectory(MAX_PATH,strTemp.GetBuffer(MAX_PATH)) == 0 )
	{
		strTemp.ReleaseBuffer();
		return FALSE;
	}
	strTemp.ReleaseBuffer(MAX_PATH);
	BOOL bRes = SetCurrentDirectory(lpszPathName);
	SetCurrentDirectory(strTemp.GetBuffer(MAX_PATH));
	strTemp.ReleaseBuffer(MAX_PATH);
	return bRes;
}

// 判断是否是路径
BOOL IsDirPath(LPCTSTR lpszPathName)
{
	HANDLE hFindFile;
	WIN32_FIND_DATA stuFindData;

	CString strName(lpszPathName);
	strName  += _T("\\*");
	hFindFile = FindFirstFile(strName, &stuFindData);
	if (hFindFile == INVALID_HANDLE_VALUE)	return FALSE;
	else
	{
		FindClose(hFindFile);
		return TRUE;
	}
}

// 取得目录下的所有文件
void CMyFtpClient::GetFileInPath(LPCTSTR lpszPath, CStringArray &arrstrFile, 
								 BOOL bFindSubDir/* = FALSE*/, LPCTSTR lpszFileExt)
{
	if (!IsPathExist(lpszPath))	return ;

	arrstrFile.RemoveAll();

	WIN32_FIND_DATA		stuFindData;
	HANDLE				hFindFile;
	CString strName(lpszPath);

	//modify by paul strName  += _T("\\*");
	//strName  += _T(lpszFileExt);
	strName  += _T("\\*");

	hFindFile = FindFirstFile(strName, &stuFindData);

	if (hFindFile == INVALID_HANDLE_VALUE)	return ;
	else
	{
		strName = stuFindData.cFileName;
		if (strName.CompareNoCase(_T(".")) != 0 && strName.CompareNoCase(_T("..")) != 0)
		{
			strName  = lpszPath;
			strName += _T("\\");
			strName += stuFindData.cFileName;
			if (!IsDirPath(strName) && strName.CompareNoCase(_T(lpszFileExt)) != 0 )
				arrstrFile.Add(strName);
			else if (bFindSubDir)
			{
				CStringArray arrstrTemp;
				GetFileInPath(strName, arrstrTemp, bFindSubDir,lpszFileExt);
				for (int i=0; i<arrstrTemp.GetSize() && strName.CompareNoCase(_T(lpszFileExt)) != 0; i++)
					arrstrFile.Add(arrstrTemp[i]);
				arrstrTemp.RemoveAll();
			}
		}
		while (FindNextFile(hFindFile, &stuFindData)) 
		{
			strName = stuFindData.cFileName;
			if (strName.CompareNoCase(_T(".")) != 0 && strName.CompareNoCase(_T("..")) != 0)
			{
				strName  = lpszPath;
				strName += _T("\\");
				strName += stuFindData.cFileName;
				if (!IsDirPath(strName) && strName.CompareNoCase(_T(lpszFileExt)) != 0 )
					arrstrFile.Add(strName);
				else if (bFindSubDir)
				{
					CStringArray arrstrTemp;
					GetFileInPath(strName, arrstrTemp, bFindSubDir,lpszFileExt);
					for (int i=0; i<arrstrTemp.GetSize() && strName.CompareNoCase(_T(lpszFileExt)) != 0; i++)
						arrstrFile.Add(arrstrTemp[i]);
					arrstrTemp.RemoveAll();
				}
			}
		}
		FindClose(hFindFile);
	}


}

//上传速度 bytes/s
DWORD  CMyFtpClient::GetUploadSpeed()
{
	/*
	m_UploadSpeed = m_CurUploadSize;
	Sleep(1000);
	m_UploadSpeed = m_CurUploadSize - m_UploadSpeed;
	return m_UploadSpeed;
	*/

	return m_CurUploadSize;
}

//下载速度 bytes/s
DWORD  CMyFtpClient::GetDownloadSpeed()
{
	/*
	m_DownloadSpeed = m_CurDownloadSize;
	Sleep(1000);
	m_DownloadSpeed = m_CurDownloadSize - m_DownloadSpeed;
	return m_DownloadSpeed;
	*/

	return m_CurDownloadSize;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值