How to download a file with WinHTTP in C/C++?

本秂侑毒 提交于 2019-11-26 11:18:13

问题


I know how to download an html/txt page. For example :

//Variables 
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
vector <string>  vFileContent;
BOOL  bResults = FALSE;
HINTERNET  hSession = NULL, 
           hConnect = NULL,
           hRequest = NULL;

// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L\"WinHTTP Example/1.0\",  
                        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                        WINHTTP_NO_PROXY_NAME, 
                        WINHTTP_NO_PROXY_BYPASS, 0);

// Specify an HTTP server.
if (hSession)
    hConnect = WinHttpConnect( hSession, L\"nytimes.com\",
                               INTERNET_DEFAULT_HTTP_PORT, 0);

// Create an HTTP request handle.
if (hConnect)
    hRequest = WinHttpOpenRequest( hConnect, L\"GET\", L\"/ref/multimedia/podcasts.html\",
                                   NULL, WINHTTP_NO_REFERER, 
                                   NULL, 
                                   NULL);

// Send a request.
if (hRequest)
    bResults = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS,
                                   0, WINHTTP_NO_REQUEST_DATA, 0, 
                                   0, 0);


// End the request.
if (bResults)
    bResults = WinHttpReceiveResponse( hRequest, NULL);

// Keep checking for data until there is nothing left.
if (bResults)
    do 
    {

        // Check for available data.
        dwSize = 0;
        if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
            printf( \"Error %u in WinHttpQueryDataAvailable.\\n\",
                    GetLastError());

        // Allocate space for the buffer.
        pszOutBuffer = new char[dwSize+1];
        if (!pszOutBuffer)
        {
            printf(\"Out of memory\\n\");
            dwSize=0;
        }
        else
        {
            // Read the Data.
            ZeroMemory(pszOutBuffer, dwSize+1);

            if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                                  dwSize, &dwDownloaded))
            {
                printf( \"Error %u in WinHttpReadData.\\n\", 
                        GetLastError());
            }
            else
            {
                        printf(\"%s\", pszOutBuffer);
                            // Data in vFileContent
                vFileContent.push_back(pszOutBuffer);
            }

            // Free the memory allocated to the buffer.
            delete [] pszOutBuffer;
        }

    } while (dwSize>0);


// Report any errors.
if (!bResults)
    printf(\"Error %d has occurred.\\n\",GetLastError());

// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);

// Write vFileContent to file
ofstream out(\"test.txt\",ios::binary);
for (int i = 0; i < (int) vFileContent.size();i++)
out << vFileContent[i];
out.close();

When I try to download a picture, I get only the first lines of the file and no error message. The problem seems related to this parameter (ppwszAcceptTypes) in WinHttpOpenRequest Function.

link text


回答1:


Looks like this thread on MSDN is the same and has the solution

http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/45ccd91c-6794-4f9b-8f4f-865c76cc146d




回答2:


Solution :

FILE * pFile; // NEW
pFile = fopen("file.bin", "w+b"); // NEW

if (bResults)
    do 
    {
        // Check for available data.
        dwSize = 0;
        if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
            printf( "Error %u in WinHttpQueryDataAvailable.\n",
                    GetLastError());

        // Allocate space for the buffer.
        pszOutBuffer = new char[dwSize+1];



        if (!pszOutBuffer)
        {
            printf("Out of memory\n");
            dwSize=0;
        }
        else
        {
            // Read the Data.
            ZeroMemory(pszOutBuffer, dwSize+1);

            if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                                  dwSize, &dwDownloaded))
            {
                printf( "Error %u in WinHttpReadData.\n", 
                        GetLastError());
            }
            else
            {
                            printf("%s", pszOutBuffer);
                fwrite(pszOutBuffer, (size_t)dwDownloaded, (size_t)1, pFile); // NEW

            }

            // Free the memory allocated to the buffer.
            delete [] pszOutBuffer;
        }

    } while (dwSize>0);

fclose (pFile); // NEW



回答3:


Merely opening the ofstream in binary mode does not change the way that the << operators work - they will always perfform formatted output. You need to use the stream's write() function, which does unformatted output.



来源:https://stackoverflow.com/questions/822714/how-to-download-a-file-with-winhttp-in-c-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!