Download demo project - 118 Kb
Download source - 44.3 Kb
Introduction
Anyone who has used the WinInet FTP functions has probably noticed that many
features are lacking. In particular, I wanted some code that:
- Supports wildcards
- Can recursively look into the sub directories for upload/download/delete
- Can upload/download multiple files with a single line of code
- Can delete multiple files/folders with a single line of code
- Can get the file listing with a single line of code
- Automatically shows a progress bar and let's the user cancel the transfer
Functions
The main class is the CFTPClient
class:
class AFX_EXT_CLASS CFTPClient
{
protected:
CInternetSession m_InternetSession;
CFtpConnection *m_pFtpConnection;
CString m_sFTPRootFolder;
void SeperateFilename (const CString &sFullName, CString &sFolder,
CString &sFilename, TCHAR cFolderSeperator);
public:
CFTPClient ();
~CFTPClient ();
bool IsInitialized ();
void Login (const CString &sHost, const CString &sUsername,
const CString &sPassword, BOOL bPASV = FALSE, int nPort = 21,
int nRetries = 1, int nRetryDelay = 10);
void Logoff ();
void Download (const CString &sRemoteFiles,
const CString &sLocalFolder,
bool *pbAbort, bool bRecursive = true,
DWORD dwTransferType = FTP_TRANSFER_TYPE_BINARY);
void Upload (const CString &sLocalFiles, const CString &sRemoteFolder,
bool *pbAbort, bool bRecursive = true,
DWORD dwTransferType = FTP_TRANSFER_TYPE_BINARY);
void DeleteFiles (const CString &sOrgRemoteFiles, bool *pbAbort,
bool bRecursive, bool bAbortIfFailsOnce);
void DeleteFolders (const CString &sRemoteFolder, bool *pbAbort,
bool bRecursive, bool bAbortIfFailsOnce);
void CreateMultiFolder (const CString &sRemoteFolder);
void GetFileList (const CString &sRemoteFolder,
bool bFullPathGiven,
CStringArray &sFileNameArray, bool bRecursive,
bool bExcludeHidden = false);
private:
void DeleteRemoteFiles (bool bDeleteFirs, const CString &sOrgRemote,
bool *pbAbort, bool bRecursive, bool bAbortIfFailsOnce);
friend class CFTPDownload;
friend class CFTPUpload;
};
void Login (const CString &sHost, const CString &sUsername, const
CString &sPassword, BOOL bPASV = FALSE, int nPort = 21, int nRetries = 1, int
nRetryDelay = 10)
To connect using passive mode, set bPASV
to TRUE
. nRetires
represents
the number of retransmissions. nRetryDelay
is the delay between each retry attempt.
void Logoff ()
Disconnects from the server.
void Download (const CString &sRemoteFiles, const CString &sLocalFolder,
bool *pbAbort, bool bRecursive = true, DWORD dwTransferType = FTP_TRANSFER_TYPE_BINARY)
sRemoteFiles
are the files to be downloaded. Usage of wildcard
characters are accepted.
-
sLocalFolder
is the destination folder.
-
pbAbort
is a pointer to a boolean. It is used to abort the transfers.
If *pbAbort
is set to true
, the function aborts the
current operation and returns.
If bRecursive
is true, then all the subfolders and their contents will also
be downloaded.
void Upload (const CString &sLocalFiles, const CString &sRemoteFolder,
bool *pbAbort, bool bRecursive = true, DWORD dwTransferType = FTP_TRANSFER_TYPE_BINARY)
sLocalFiles
are the files to be uploaded. Usage of wildcard
characters are accepted.
-
sRemoteFolder
is the destination folder.
-
pbAbort
is a pointer to a boolean. It is used to abort the transfers.
If *pbAbort
is set to true
, the functions aborts the current operation
and returns.
If bRecursive
is true
, then all the subfolders and their contents will also
be uploaded.
void DeleteFiles (const CString &sOrgRemoteFiles, bool *pbAbort,
bool bRecursive, bool bAbortIfFailsOnce)
-
sOrgRemoteFiles
are the files to be deleted. Usage of wildcard characters are
allowed.
-
pbAbort
is a pointer to a boolean. It is used to abort the transfers.
If *pbAbort
is set to true
, the function aborts the current operation
and returns.
If bRecursive
is true
, then all the files in the subfolders will also be deleted.
If bAbortIfFailsOnce
is set to true, then the function will abort on the first
error. Otherwise, it will try to delete the other files and then return.
void DeleteFolders (const CString &sRemoteFolder, bool *pbAbort,
bool bRecursive, bool bAbortIfFailsOnce)
sOrgRemoteFolders
are the folders to be deleted. Usage of wildcard
characters are allowed. Please note that, the folder MUST be empty before the
deletion. You can use DeleteFiles
function to delete the contents of the folders
and then use DeleteFolders
function to delete the empty folders.
-
pbAbort
is a pointer to a boolean. It is used to abort the transfers.
If *pbAbort
is set to true, the function aborts the current operation
and returns.
If bRecursive
is true
, then all the files in the subfolders will also be deleted.
If bAbortIfFailsOnce
is set to true
, then the function will abort on the first
error. Otherwise, it will try to delete the other files and then return.
void CreateMultiFolder (const CString &sRemoteFolder)
sRemoteFolder
is the folder to be created.
If in order to create
sRemoteFolder
multiple folders should be created, the function automatically
creates the lower level directories first. For example, suppose you want to
create a folder /html/my_folder1/my_folder2/my_folder3. If my_folder1 does not
exist, then the function first creates my_folder1 and then my_folder2 and lastly
my_folder3.
void GetFileList (const CString &sRemoteFolder, bool bFullPathGiven,
CStringArray &sFileNameArray, bool bRecursive, bool bExcludeHidden = false)
Puts all the filenames into sFileNameArray
. bFullPathGiven
should
be set to false
.
Exception Handling
All of the functions above throws CFTPException
. Here is the
CFTPException
class:
class AFX_EXT_CLASS CFTPException : public CException
{
public:
enum FTPError
{
FTP_Unknown,
FTP_LoginFailed,
FTP_AlreadyConnected,
FTP_NotConnected,
FTP_Local_FileCreateFailed,
FTP_Local_FileOpenFailed,
FTP_Local_UnknownFileError,
FTP_Remote_SetCurDirFailed,
FTP_Remote_FileOpenFailed,
FTP_Remote_FileWriteFailed,
FTP_CreateFolderFailed,
FTP_DeleteFilesFailed,
FTP_DeleteFoldersFailed,
FTP_DeleteRootFolderNotAllowed,
FTP_InvalidLocalFileName,
FTP_InvalidRemoteFileName,
FTP_UserAborted
};
int m_nError;
CString m_sDesc;
CFTPException (FTPError nError,
const CString &sDesc) : CException (TRUE)
{
m_nError = nError;
m_sDesc = sDesc;
}
};
-
FTP_Unknown:
An unknown error occurred. See sDesc
for details.
-
FTP_LoginFailed:
Login to the server failed. See sDesc
for details.
-
FTP_AlreadyConnected:
The object already has an active connection.
First call Logoff ()
to close the connection.
-
FTP_NotConnected:
The object has no active connection yet. Call Login function first.
-
FTP_Local_FileCreateFailed:
Cannot create the local file. See sDesc
for details.
-
FTP_Local_FileOpenFailed:
Cannot open the specified local file. See sDesc
for details.
-
FTP_Local_UnknownFileError:
An unknown file error occurred. See sDesc
for details.
-
FTP_Remote_SetCurDirFailed:
Setting current FTP directory failed. The directory may not exist or you may not have permissions to
access the directory. See sDesc
for details.
-
FTP_Remote_FileOpenFailed:
Cannot read from the remote file. The file may not exist or you may not have the permissions to read that file. See sDesc
for details.
-
FTP_Remote_FileWriteFailed:
Cannot write to the remote file. The filename given may be invalid, or you may not have the permissions to write to that file. See sDesc
for details.
-
FTP_CreateFolderFailed:
Cannot create the folder. If it is on the remote machine, be sure that you have permissions to create a folder. Also be sure that another file does not have the destination folder name. See sDesc
for details.
-
FTP_DeleteFilesFailed:
Cannot delete files from the server. Be sure that you have the permissions to delete files. See sDesc
for details.
-
FTP_DeleteFoldersFailed:
Cannot delete folders from the server. Be sure that the folders are empty and you have the permissions to delete folders. See sDesc
for details.
-
FTP_DeleteRootFolderNotAllowed:
Deletion of root folder is not allowed!
-
FTP_InvalidLocalFileName:
The filename given is invalid. See
sDesc
for details.
-
FTP_InvalidRemoteFileName:
The filename given is invalid. See
sDesc
for details.
-
FTP_UserAborted:
User pressed the cancel button and thus the
transfer is aborted.
Usage
In order to use these classes, you should:
- Include FTPClient.h.
- In StdAfx.h, include <afxinet.h> for MFC Internet support.
- Add WinInet.lib to the Object/Library Modules section in Linker options.
- Copy FTPClient.dll to your executable's folder.
Examples
Upload some files to the server
try
{
bool bAbort = false;
m_FTPClient.Upload ("c:\\my_web\\*", "public_html/", &bAbort, true);
}
catch (CFTPException *pEx)
{
switch (pEx->m_nError)
{
case FTP_NotConnected:
break;
}
CString sDesc = pEx->m_sDesc;
pEx->Delete ();
AfxMessageBox (sDesc);
}
Download files from the server
try
{
bool bAbort = false;
m_FTPClient.Download ("public_html/*", "c:\\my_web\\", &bAbort, true);
}
catch (CFTPException *pEx)
{
switch (pEx->m_nError)
{
// You can check for all exception types here!
case FTP_NotConnected:
break;
}
CString sDesc = pEx->m_sDesc;
pEx->Delete ();
AfxMessageBox (sDesc);
}
Delete all files and folders
try
{
bool bAbort = false;
m_FTPClient.DeleteFiles ("tmp/*", &bAbort, true, true);
m_FTPClient.DeleteFolders ("tmp/*", &bAbort, true, true);
}
catch (CFTPException *pEx)
{
switch (pEx->m_nError)
{
case FTP_NotConnected:
break;
}
CString sDesc = pEx->m_sDesc;
pEx->Delete ();
AfxMessageBox (sDesc);
}
A Demo Program
The demo program uses FTPClient.dll and implements a very primitive FTP program.
Thanks
- To Pablo van der Meer for FTPWanderer.
- To Antonio Tejada Lacaci for CFileInfoArray class.
- To The Code Project, for providing a useable forum for all of us.
Some points that you should keep in mind
- I have not tested these classes extensively yet. There may be some bugs
in the code.