URLDownloadToFile

在服务中、一般程序中利用 Inet 相关函数下载数据[原创]
虽然可以使用 URLDownloadFileToXXX() 这个 API,但是,它在使用了代理的时候会遇到麻烦。
这点,Windows 自动更新发生过这样的问题:如果使用了 IE 代理,如果下载代码位于系统帐号
下,代理设置可能会失效。当然,也可以为系统帐号手动设置代理(其实就是 IE 的代理的设置
方法),不过,程序会受到很多的限制。

所以,可以考虑使用下属两个函数进行使用 - 服务程序亦可。
// Download a file from the URL.
bool CHttpDownload::UrlDownloadToFile(TCHAR *ptszURL, TCHAR *ptszFilePath)
{
      
        HINTERNET                                hNet;
        HINTERNET                                hFile;
        std::string                                sProxyServer;

        DWORD                                        dwStatusCode;
        TCHAR                                        dwStatusCode1[32] = {0};
        DWORD                                        dwSize1 = sizeof(dwStatusCode1),        dwSize = sizeof(DWORD);
      
        int                                                nfilesize;                        // file size, 2GB limited. ;)

        m_sUrl = ptszURL;
        //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() ++");

        //
        if(m_ConnectionType == UseProxy)
        {
                //OutputDebugString("\n ==> Useproxy");
                hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PROXY, m_sProxy.c_str(), NULL, 0);
        }
        else if(m_ConnectionType == DirectToInternet)      
        {
                //OutputDebugString("\n ==> DirectToInternet");
                hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
        }
        else if(m_ConnectionType == UsePreConfig)      
        {
                //OutputDebugString("\n ==> UsePreConfig");
                hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
        }


        if(hNet == NULL)
        {
                //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.1");
                return false;
        }

        hFile = InternetOpenUrl(hNet, m_sUrl.c_str(), NULL, 0, 0, 0);
        if(hFile == NULL)
        {
                InternetCloseHandle(hNet) ;
                //OutputDebugString(m_sUrl.c_str());
                //OutputDebugString(ptszURL);
                //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.2");

                return false;
        }
      
        BOOL bRet = HttpQueryInfo(hFile, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,&dwSize,NULL);
        if(200 != dwStatusCode)                // if URI is not exist, give up.
        {
                InternetCloseHandle(hNet) ;
                InternetCloseHandle(hFile) ;
                //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.3");

                return false;
        }
        if(HttpQueryInfo(hFile,HTTP_QUERY_CONTENT_LENGTH, &dwStatusCode1,&dwSize1,NULL))
        {
                nfilesize = atoi(dwStatusCode1);                // file size.
        }
      
        HANDLE hDownFile = CreateFile(ptszFilePath,
                                                                GENERIC_READ|GENERIC_WRITE,
                                                                FILE_SHARE_READ,
                                                                NULL,
                                                                CREATE_ALWAYS,
                                                                FILE_ATTRIBUTE_NORMAL,
                                                                NULL);

        if(INVALID_HANDLE_VALUE == hDownFile)
        {
                InternetCloseHandle(hNet) ;
                InternetCloseHandle(hFile) ;
                //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.4");

                return false;
        }

        // O.K. save file
        DWORD dwWrite, dwBytesRead = 0;
        char  bufFile[MAX_BUFFER_SIZE] = {0};
        DWORD dwSurplus = nfilesize % sizeof(bufFile);      

        while(true)
        {
                // Read File Data From Net.
                BOOL bRead = InternetReadFile(hFile, bufFile, sizeof(bufFile), &dwBytesRead);
                if(dwBytesRead == 0)                // End of file.
                        break;

                // Write file data.
                WriteFile(hDownFile, bufFile, dwBytesRead, &dwWrite,NULL);
        }

        InternetCloseHandle(hFile) ;
        InternetCloseHandle(hNet) ;
        CloseHandle(hDownFile) ;

        //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.");
        return true;
}

// Download URL contents to memory buffer.
// if pBuf == NULL, *pdwBufSize will contain the real size of remote size;
// *pdwBufSize alwayls contains the size of remote size.
bool CHttpDownload::UrlDownloadToBuffer(TCHAR *ptszURL, LPVOID pBuf, DWORD *pdwBufSize)
{
      
        HINTERNET                                hNet;
        HINTERNET                                hFile;
        std::string                                sProxyServer;
      
        DWORD                                        dwStatusCode;
        TCHAR                                        dwStatusCode1[32] = {0};
        DWORD                                        dwSize1 = sizeof(dwStatusCode1),        dwSize = sizeof(DWORD);
      
        int                                                nfilesize;                        // file size, 2GB limited. ;)
      
        m_sUrl                = ptszURL;
      
        //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() ++");
      
        //
        if(m_ConnectionType == UseProxy)
                hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PROXY, m_sProxy.c_str(), NULL, 0);
        else if(m_ConnectionType == DirectToInternet)      
                hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
        else if(m_ConnectionType == UsePreConfig)      
                hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
      
      
        if(hNet == NULL)
        {
                //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.1");
                return false;
        }
      
        hFile = InternetOpenUrl(hNet, m_sUrl.c_str(), NULL, 0, 0, 0);
        if(hFile == NULL)
        {
                InternetCloseHandle(hNet) ;
                //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.2");
              
                return false;
        }
      
        BOOL bRet = HttpQueryInfo(hFile, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,&dwSize,NULL);
        if(200 != dwStatusCode)                // if URI is not exist, give up.
        {
                InternetCloseHandle(hNet) ;
                InternetCloseHandle(hFile) ;
                //OutputDebugString("\nCHttpDownload::UrlDownloadToFile() --.3");
              
                return false;
        }
        if(HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH, &dwStatusCode1, &dwSize1, NULL))
        {
                nfilesize = atoi(dwStatusCode1);                // file size.
              
        }
      
        char                                szBuffer[MAX_BUFFER_SIZE+1] = {0};
        if(pBuf != NULL)        // We only copy the 1st MAX_BUFFER_SIZE data to user buffer!!!
        {
                unsigned long nSize = 0;               
                BOOL bRet = InternetReadFile(hFile, szBuffer, MAX_BUFFER_SIZE, &nSize);
                szBuffer[nSize] = '\0';
                // dump buffer.
                DWORD        dwtSize = (*pdwBufSize > nSize)? nSize: *pdwBufSize;
                memcpy(pBuf, szBuffer, dwtSize);
        }      
        *pdwBufSize = nfilesize;
        InternetCloseHandle(hFile) ;
        InternetCloseHandle(hNet) ;
        return true;      
}

注意,
用HTTP_QUERY_CONTENT_LENGTH只是返回本次请求得到数据的长度,如果要得到整个文件的大小,
用HTTP_QUERY_CONTENT_RANGE,然后解析得到的字符串,就可以了。
HTTP_STATUS_OK = 200

***************************************************************************************

用CHttpFile实现简单的GET/POST数据

一、GET 数据,下载网页,文件等,用于可下载的文件,不能用于服务端运行的程序,比如.aspx文件等,否则会返回500错误。

    CString strSentence, strWriteName="1.htm";
    CString strFileName="http://localhost/InDesign/" + strWriteName;
    CInternetSession sess;
    CHttpFile* fileGet;
    try
    {
        fileGet=(CHttpFile*)sess.OpenURL(strFileName);
    }
    catch(CException* e)
    {
        fileGet = 0;
        throw;
    }   

    if(fileGet)
    {
        DWORD dwStatus;
        DWORD dwBuffLen = sizeof(dwStatus);
        BOOL bSuccess = fileGet->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);

        if( bSuccess && dwStatus>= 200 && dwStatus<300 )
        {
            CStdioFile fileWrite;
            if(fileWrite.Open(strWriteName, CFile::modeWrite|CFile::modeCreate))
            {
                while(fileGet->ReadString(strSentence))
                {
                    fileWrite.WriteString(strSentence+"\n");
                }
                fileWrite.Close();
                AfxMessageBox("下载完毕");
            }
            else
            {
                AfxMessageBox("本地文件"+strWriteName+"打开出错.");
            }
        }
        else
        {
            strSentence.Format("打开网页文件出错,错误码:%d", dwStatus);
            AfxMessageBox(strSentence);
        }
        fileGet->Close();
        delete fileGet;
    }
    else
        AfxMessageBox("不能找到网页文件!");

    sess.Close();

二、POST 数据,比如用于提交注册信息等
CString strHttpName="http://localhost/TestReg/RegForm.aspx"; // 需要提交数据的页面
    CString strFormData = "username=abc&password=123";    // 需要提交的数据

    CInternetSession sess;
    CHttpFile* fileGet;
    CString strHeaders = _T("Content-Type: application/x-www-form-urlencoded"); // 请求头

    try
    {
        fileGet=(CHttpFile*)sess.OpenURL(strHttpName);//打开文件
    }
    catch(CException* e)
    {
        fileGet = 0;
        throw;
    }

    CString strSentence, strGetSentence = "";
    if(fileGet)
    {
        DWORD dwStatus;
        DWORD dwBuffLen = sizeof(dwStatus);
        BOOL bSuccess = fileGet->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
        if( bSuccess && dwStatus>= 200 &&dwStatus<300 )
        {
            BOOL result = fileGet->SendRequest(strHeaders, (LPVOID)(LPCTSTR)strFormData, strFormData.GetLength());
            while(fileGet->ReadString(strSentence))    // 读取提交数据后的返回结果
            {
                strGetSentence = strGetSentence + strSentence + char(13) + char(10);
            }
            AfxMessageBox(strGetSentence); // 显示返回网页内容
        }
        else
        {
            strSentence.Format("POST出错,错误码:%d", dwStatus);
            AfxMessageBox(strSentence);
        }
       
        fileGet->Close();
        delete fileGet;
    }
    else
        AfxMessageBox("不能找到网页文件!");
    sess.Close();

当然也可以用直接用Api函数URLDownloadToFile()来下载一个文件.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值