2009-05-05 33 views
10

私はhtml/txtページをダウンロードする方法を知っています。例:C/C++で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ライブラリやジャグリング証明書よりもはるかに簡単です。 https://msdn.microsoft.com/en-us/library/ms759148(v=vs.85).aspx – jmucchiello

答えて

2
+0

これまでにこのスレッドを読んだことがありますが、解決策(バイナリモードでファイルを開く)が機能しませんでした私のために。 しかし、今度はC言語ではなくC言語を使って再試行しました。ですから、ofstreamはWinHttpでは動作しません。 –

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のを開くことを< <の演算子が動作する方法 - 常に実行されますフォーマットされた出力。フォーマットされていない出力を行うストリームのwrite()関数を使用する必要があります。

関連する問題