最近在做一个项目,需要把一个internet网上的Url文件下载到本地,下面是我使用的一些代码
该代码支持线程.
头文件:
#pragma once
#include "afxmt.h"
#include "wininet.h"
#define WM_HTTP_DOWNLOAD_FINISH WM_USER + 200
enum e_Down_ErrorCode
{
e_Down_ErrorCode_Lock = 1,
e_Down_ErrorCode_HttpQueryInfo = 2,
e_Down_ErrorCode_OpenFile = 3,
e_Down_ErrorCode_Length = 4,
e_Down_ErrorCode_IO_PENDING = 5
};
class CDownload
{
public:
CDownload(void);
~CDownload(void);
enum STATUS
{
STATUS_IDLE,
STATUS_OPENING,
STATUS_DOWNLOADING,
STATUS_COMPLETE,
STATUS_ERROR,
};
void Start(CString strUrl, CString strFilePath ,int nDowStype , CDialog* pParent);
private:
static UINT _ThreadEntry(LPVOID lpvParam);
void Thread();
private:
CString m_strUrl;
CString m_strFilePath;
int m_nDownType;
CDialog* m_pParent;
};
实现文件:
#include "StdAfx.h"
#include "Download.h"
#include <list>
#include "AsiaTrader.h"
using namespace std;
CDownload::CDownload(void)
{
}
CDownload::~CDownload(void)
{
}
void CDownload::Start(CString strUrl, CString strFilePath , int nDowStype ,CDialog* pParent)
{
m_strUrl = strUrl;
m_strFilePath = strFilePath;
m_nDownType = nDowStype;
m_pParent = pParent ;
AfxBeginThread(_ThreadEntry, this);
}
UINT CDownload::_ThreadEntry(LPVOID lpvParam)
{
CDownload *pThis = (CDownload *) lpvParam;
pThis->Thread();
return 0;
}
void CDownload::Thread()
{
char * pBuf = NULL ;
int nBufLen = 0 ;
TRY
{
// connection
CInternetSession sess ;
sess.SetOption (INTERNET_OPTION_CONNECT_TIMEOUT, Query_TimeOut_Time) ;
sess.SetOption (INTERNET_OPTION_CONNECT_BACKOFF, 1000) ;
sess.SetOption (INTERNET_OPTION_CONNECT_RETRIES, 1) ;
DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD ;
CHttpFile * pF = (CHttpFile*)sess.OpenURL(m_strUrl, 1, dwFlag);
ASSERT(pF);
if (!pF)
{
AfxThrowInternetException(1);
}
// connection status
CString str ;
pF->QueryInfo (HTTP_QUERY_STATUS_CODE, str) ;
// Proxy Authentication Required
if (str == _T("407"))
{
CString strUsername, strPassword ;
pF->SetOption (INTERNET_OPTION_PROXY_USERNAME, (VOID*)(LPCTSTR)strUsername, strUsername.GetLength()) ;
pF->SetOption (INTERNET_OPTION_PROXY_PASSWORD, (VOID*)(LPCTSTR)strPassword, strPassword.GetLength()) ;
pF->SendRequest (NULL) ;
}
pF->QueryInfo (HTTP_QUERY_STATUS_CODE, str) ;
if (str != _T("200"))
{
pF->Close() ;
delete pF ;
AfxThrowInternetException(1);
}
// start download
pF->QueryInfo (HTTP_QUERY_CONTENT_LENGTH, str) ; // file's length
if (_ttoi(str))
{
// know file's size
int nLen = (nBufLen = _ttoi(str)) ;
char * p = (pBuf = new char[nLen+8]) ;
ZeroMemory (p, nLen+8) ;
while ( TRUE)
{
// download 8K every
int n = pF->Read (p, (nLen < 8192) ? nLen : 8192) ;
if (n <= 0)
break ; // success exit
p += n ;
nLen -= n ;
}
// interrupted
if (nLen != 0)
{
delete[] pBuf; pBuf=NULL;
nBufLen = 0 ;
}
}
pF->Close() ;
delete pF ;
}
CATCH_ALL(e)
{
}
END_CATCH_ALL
if (pBuf)
{
CFile outFile (m_strFilePath, CFile::modeCreate|CFile::modeReadWrite);
outFile.Write (pBuf,nBufLen) ;
outFile.Close();
m_pParent->SendMessage(WM_HTTP_DOWNLOAD_FINISH,1,m_nDownType);
delete[] pBuf ;
}
else
{
m_pParent->SendMessage(WM_HTTP_DOWNLOAD_FINISH,0,m_nDownType);
return ;
}
return ;
}