2009-05-05 5 views
10

Ich weiß, wie man eine HTML/TXT-Seite herunterladen. Zum Beispiel:Wie lade ich eine Datei mit WinHTTP in C/C++ herunter?

//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(); 

Wenn ich versuche, ein Bild zum Download, erhalte ich nur die ersten Zeilen der Datei und keine Fehlermeldung. Das Problem scheint mit diesem Parameter (ppwszAcceptTypes) in WinHttpOpenRequest Function verwandt zu sein.

link text

+0

Nur eine kleine Bemerkung zu Ihrer dynamischen Speicherzuweisung - Sie ordnen sie wie 'pszOutBuffer = new char [dwSize + 1];' und danach den Zeiger. Das sollten Sie nicht tun, da der neue Operator standardmäßig eine Ausnahme bei Speichermangel auslöst. Um dies zu verhindern, sollten Sie 'std :: nothrow' dem neuen Operator wie folgt übergeben: 'pszOutBuffer = new (std :: nothrow) char [dwSize + 1];' - In diesem Fall ist der Zeiger bei einem Mangel null der Erinnerung. –

+0

Importieren Sie die msxml6-Bibliothek. Es wird mit (vista vielleicht? Win7 für sicher und oben) geliefert und ist auf XP installierbar. Initiiere COM und das Erzeuge ein IXMLHTTPRequest Objekt und sende eine Anfrage. Viel einfacher als WinHttp-Bibliotheken und Jonglier-Zertifikate. https://msdn.microsoft.com/en-us/library/ms759148(v=vs.85).aspx – jmucchiello

Antwort

6

Lösung:

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 
5

Lediglich die ofstream im Binär-Modus ändert sich nicht öffnen Die Art und Weise, wie die < < Operatoren arbeiten - sie werden immer perfform formatierte Ausgabe Sie müssen die write() -Funktion des Streams verwenden, die unformatierte Ausgaben ausführt.

Verwandte Themen