怎么样使用CFtpconnection类实现文件的断点续传?

怎么样使用CFtpconnection类实现文件的断点续传?

下面是我写的下载和上传的线程,其中下载时无法改变服务器端的读文件指针,只是改变了本地文件指针,所以只有读前面已下部分时不写,这样可以提高一点速度,但还是不算断点续传.而上传就更难以实现了.

下面的程序可以运行,也可以实现ftp的基本功能.

UINT CFtpView::FileThread( LPVOID lpInf )
{
FTP_INFO *lpInfo = (FTP_INFO *) lpInf;

CInternetSession *lpInetSession;
CFtpConnection *lpFtpConnection;

// Allocate a CInternetSession object.
lpInetSession = new CInternetSession(
lpInfo->szAppName, 1,
PRE_CONFIG_INTERNET_ACCESS );

// If the CInternetSession object didn't
// allocate, bail out.
if( lpInetSession == NULL ){
delete lpInfo;
return( 0 );
}

// Attempt to make the Ftp connection.
try{

// We'll use a NULL pointer for the
// user name since GetFtpConnection()
// will use a default value if it
// gets a NULL for it. If a user
// name was given by user, go ahead and
// point to that string.
char *lpUser = NULL;
if( lpInfo->szUser[0] != 0 )
lpUser = lpInfo->szUser;

// The same thing happens here for the
// password. Use a NULL pointer unless
// user gave a password.
char *lpPassword = NULL;
if( lpInfo->szPassword[0] != 0 )
lpPassword = lpInfo->szPassword;

lpFtpConnection =
lpInetSession->GetFtpConnection(
lpInfo->szHost, lpUser, lpPassword );
}

// If GetFtpConnection() throws an exception,
// catch it, clean up, and return.
catch( CInternetException *lpEx ){
lpEx->Delete();
delete lpInetSession;
delete lpInfo;
return( 0 );
}


try {
CInternetFile *pInternetFile;
CFile* pFile = NULL;
CFileFind finder;
BOOL bFile;
DWORD dwLocalFilelen;
DWORD dwFtpFilelen;

//seach localfile and see whether is exist
//and get it's length
// start working for files
BOOL bWorking = finder.FindFile((CString)lpInfo->szLocalFile+"*");
while (bWorking)
{
bWorking = finder.FindNextFile();
bFile = 1;
// skip . and .. files; otherwise, we'd
// recur infinitely!
if (finder.IsDots())
continue;
}
//if the file was exist,get the length
if( bFile ) {
pFile = new CFile(lpInfo->szLocalFile,
CFile::modeRead | CFile::shareDenyNone);
dwLocalFilelen = (DWORD)pFile->GetLength();
}
//if the file wasn't exist,set the length zero;
else {
dwLocalFilelen = 0;
}
if (pFile != NULL) {
pFile->Close();
delete pFile;
}

//seach remote file and see whether is exist
//and get its length
CFtpFileFind *pFtpFind = new CFtpFileFind(lpFtpConnection);
BOOL res = pFtpFind->FindFile( (CString)lpInfo->szFtpFile+"*");
if(res)
{
pFtpFind->FindNextFile();
CString strFilename = pFtpFind->GetFileName();
// if the file was exist,get the length
dwFtpFilelen = (DWORD)pFtpFind->GetLength();
}
//if the file wasn't exist,set the length zero;
else {
dwFtpFilelen = 0;
}
if (pFtpFind != NULL) {
pFtpFind->Close();
delete pFtpFind;
}

CFile wrFile;
DWORD Percent;
DWORD dwStart;
DWORD dwEnd;
float Speed;
DWORD dwTotalReaded = 0;
DWORD dwReaded = 0;
char buffer[1024]; //存放文件数据的buffer
memset(buffer , 0 , 1024);
// Attempt to send the file from
// the local machine to the remote server.
if( lpInfo->bSendFlag ){
//check the remote file see whether it had already sent
if( dwFtpFilelen >= dwLocalFilelen) {
AfxMessageBox( "The file had already sent." );
}
else {
//if it wasnit exist,send it
if(dwFtpFilelen == 0) {
lpFtpConnection->PutFile( lpInfo->szLocalFile,
lpInfo->szFtpFile );
dwFtpFilelen = dwLocalFilelen;
}

//if it existed but wasn't sent completly,continu sent
else {
pInternetFile = lpFtpConnection->OpenFile( lpInfo->szFtpFile,GENERIC_WRITE );
CFile newFile(lpInfo->szLocalFile, CFile::modeRead|CFile::shareDenyNone);
while(dwReaded = newFile.Read(buffer ,1024))//循环读取数据
{
dwTotalReaded += dwReaded;
pInternetFile->Write(buffer ,dwReaded);
Percent = ((float)dwTotalReaded / dwLocalFilelen)*100;
}
newFile.Close( );
}
AfxMessageBox( "The file was sent." );
}
}

// Attempt to retrieve the file from
// the remote server to the local machine.
else {
if( dwFtpFilelen <= dwLocalFilelen) {
AfxMessageBox( "The file had already retrieved." );
}
else {
pInternetFile = lpFtpConnection->OpenFile( lpInfo->szFtpFile );
if( dwLocalFilelen == 0 )
wrFile.Open(lpInfo->szLocalFile, CFile::modeCreate|CFile::modeWrite | CFile::typeBinary|CFile::shareDenyNone);
else {
wrFile.Open(lpInfo->szLocalFile, CFile::modeWrite| CFile::typeBinary|CFile::shareDenyNone);
wrFile.Seek( (LONGLONG)dwLocalFilelen,CFile::begin);
}
while( dwStart = GetTickCount(),dwReaded = pInternetFile->Read(buffer ,1024))//循环读取数据
{
dwTotalReaded += dwReaded;
if( dwTotalReaded <= dwLocalFilelen )
Percent = ((float)dwLocalFilelen / dwFtpFilelen)*100;
else {
wrFile.Write(buffer ,dwReaded);
Percent = ((float)dwTotalReaded / dwFtpFilelen)*100;
}
dwEnd = GetTickCount();
Speed = (float)977/(dwStart - dwEnd);
}
AfxMessageBox( "The file was retrieved." );
wrFile.Close( );
}
}
if(pInternetFile != NULL) {
pInternetFile->Close();
delete pInternetFile;
pInternetFile = NULL;
}
}
catch(CInternetException* e)
{
e->ReportError();
e->Delete();
return 0;
}

// Close the Ftp connection and delete
// the CFtpConnection and CInternetSession
//objects.
lpFtpConnection->Close();
delete lpFtpConnection;
delete lpInetSession;
delete lpInfo;

return( 0 );

}