2009-05-05 15 views
10

मुझे पता है कि एक html/txt पृष्ठ कैसे डाउनलोड करें। उदाहरण के लिए:सी/सी ++ में WinHTTP के साथ फ़ाइल कैसे डाउनलोड करें?

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

जब मैं एक तस्वीर डाउनलोड करने के लिए प्रयास करते हैं, मैं केवल फ़ाइल और कोई त्रुटि संदेश के पहले लाइनों मिलता है। समस्या WinHttpOpenRequest फ़ंक्शन में इस पैरामीटर (ppwszAcceptTypes) से संबंधित प्रतीत होती है।

link text

+0

आपके गतिशील स्मृति आवंटन पर बस थोड़ी सी टिप्पणी - आप इसे 'pszOutBuffer = new char [dwSize + 1];' के रूप में आवंटित करते हैं और उसके बाद सूचक की जांच करें। आपको नहीं करना चाहिए, क्योंकि नया ऑपरेटर डिफ़ॉल्ट रूप से स्मृति की कमी के मामले में अपवाद फेंक देगा। इसे रोकने के लिए आपको इस 'pszOutBuffer = new (std :: nothrow) char [dwSize + 1] जैसे नए ऑपरेटर को 'std :: nothrow' की आपूर्ति करनी चाहिए;' - उस स्थिति में यदि कोई कमी है तो पॉइंटर शून्य हो जाएगा स्मृति की –

+0

msxml6 लाइब्रेरी आयात करें। यह जहाज (विस्टा शायद? Win7 निश्चित और ऊपर के लिए) के साथ जहाज और XP पर स्थापित है। COM आरंभ करें और IXMLHTTPRequest ऑब्जेक्ट बनाएं और एक अनुरोध भेजें। WinHttp पुस्तकालयों और जॉगलिंग certs से बहुत आसान है। https://msdn.microsoft.com/en-us/library/ms759148(v=vs.85).aspx – jmucchiello

उत्तर

2

लग रहा है MSDN पर इस धागे की तरह ही है और समाधान

है

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

+0

मैंने पहले इस धागे को पढ़ा है, लेकिन समाधान (बाइनरी मोड में फ़ाइल खोलना) काम नहीं किया मेरे लिए। लेकिन मैंने अभी इसे पुनः प्रयास किया है, इस बार सी का उपयोग कर, सी ++ नहीं, और यह काम करता है। तो जहां तक ​​मैं कह सकता हूं, Winstttp के साथ ऑफस्ट्रीम काम नहीं कर रहा है। –

6

समाधान:

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

केवल बाइनरी मोड में ofstream खोलने परिवर्तन नहीं करता है जिस तरह से < < ऑपरेटर काम करते हैं - वे हमेशा perfform स्वरूपित आउटपुट। आपको स्ट्रीम के लेखन() फ़ंक्शन का उपयोग करने की आवश्यकता है, जो अनौपचारिक आउटपुट करता है।

संबंधित मुद्दे