用C++實現下載檔案的功能

jsjliuyun發表於2014-09-17

       今天同學問了個C++實現給定的下載連結進行下載並儲存檔案,上網搜尋下,看到網上這類東西,所以就直接拿來個改了下,因為他的程式碼是在VC++中可以,我匯入到VS2010中出現點小問題,所以改了下貼了個VS中親測可執行的程式碼。在此記錄下。

參考的資料   http://bbs.csdn.net/topics/390052882   感覺裡面大家討論的都不錯

其實這個使用到MFC中的一些函式,可以做成圖形介面的。

下面貼下自己小小修改的程式碼

//#define _WIN32_WINNT 0x0502
#include <afx.h>
#include <afxinet.h>
#include <iostream>
using namespace std;
#define RECVPACK_SIZE 2048
bool DownloadSaveFiles(const char* url,const char* strSaveFile) {//下載檔案並儲存為新檔名
    bool ret=false;
    CInternetSession Sess(_T("lpload"));
    Sess.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT     , 5000); //5秒的連線超時
    Sess.SetOption(INTERNET_OPTION_SEND_TIMEOUT        , 5000); //5秒的傳送超時
    Sess.SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT     , 5000); //5秒的接收超時
    Sess.SetOption(INTERNET_OPTION_DATA_SEND_TIMEOUT   , 5000); //5秒的傳送超時
    Sess.SetOption(INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, 5000); //5秒的接收超時
    DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD ;

    CHttpFile* cFile   = NULL;
    char      *pBuf    = NULL;
    int        nBufLen = 0   ;
    do {
        try{
            cFile = (CHttpFile*)Sess.OpenURL((CString)url,1,dwFlag);
            DWORD dwStatusCode;
            cFile->QueryInfoStatusCode(dwStatusCode);
            if (dwStatusCode == HTTP_STATUS_OK) {
                //查詢檔案長度
                DWORD nLen=0;
                cFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, nLen);
                //CString strFilename = GetFileName(url,TRUE);
                nBufLen=nLen;
				//cout << "nLen=" << nLen << endl;
                if (nLen <= 0) break;//

                //分配接收資料快取
                pBuf = (char*)malloc(nLen+8);
                ZeroMemory(pBuf,nLen+8);

                char *p=pBuf;
                while (nLen>0) {
                    //每次下載8K
                    int n = cFile->Read(p,(nLen<RECVPACK_SIZE)?nLen:RECVPACK_SIZE);
                    //接收完成退出迴圈
                    if (n <= 0) break;//
                    //接收快取後移
                    p+= n ;
                    //剩餘長度遞減
                    nLen -= n ;
					//cout << "nLen=" << nLen << endl;
                }

                //如果未接收完中斷退出
                if (nLen != 0) break;

                //接收成功儲存到檔案

                CFile file((CString)strSaveFile, CFile::modeCreate | CFile::modeWrite);
                file.Write(pBuf,nBufLen);
                file.Close();
                ret = true;
            }
        } catch(...) {
			cout << "異常" << endl;
            break;//
        }
    } while(0);

    //釋放快取
    if (pBuf) {
        free(pBuf);
        pBuf=NULL;
        nBufLen = 0 ;
    }

    //關閉下載連線
    if (cFile) {
        cFile->Close();
        Sess.Close();
        delete cFile;
    }
    return ret;
}
int main() {
	//測試用例
    if(DownloadSaveFiles("http://www.nirsoft.net/utils/nircmd.zip","d:/cppdld_nircmd.zip") == true)
	{
		cout << "下載成功" << endl;
	}else{
		cout << "下載失敗"<< endl;
	}
    return 0;
}

相關文章