Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The <a href="http://msdn.microsoft.com/en-us/library/aa385103(v=vs.85).aspx" rel="noreferrer">documentation</a> makes the following remarks:</p> <blockquote> <p>InternetReadFile operates much like the base ReadFile function, with a few exceptions. Typically, InternetReadFile retrieves data from an HINTERNET handle as a sequential stream of bytes. The amount of data to be read for each call to InternetReadFile is specified by the dwNumberOfBytesToRead parameter and the data is returned in the lpBuffer parameter. A normal read retrieves the specified dwNumberOfBytesToRead for each call to InternetReadFile until the end of the file is reached. <strong>To ensure all data is retrieved, an application must continue to call the InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.</strong></p> </blockquote> <p>Basically, there is no guarantee that the function to read exactly <code>dwNumberOfBytesToRead</code>. Check out how many bytes were actually read using the <code>lpdwNumberOfBytesRead</code> parameter. </p> <p>Moreover, as soon as the total file size is larger than <code>dwNumberOfBytesToRead</code>, you will need to invoke the call multiple times. Because it cannot read more than <code>dwNumberOfBytesToRead</code> at once.</p> <p>If you have the total file size in advance, the loop takes the following form:</p> <pre><code>::DWORD error = ERROR_SUCCESS; ::BYTE data[SIZE]; // total file size. ::DWORD size = 0; ::DWORD read = 0; do { ::BOOL result = ::InternetReadFile(stream, data+size, SIZE-size, &amp;read); if ( result == FALSE ) { error = ::GetLastError(); } } while ((error == ERROR_SUCCESS) &amp;&amp; (read &gt; 0) &amp;&amp; ((size+=read) &lt; SIZE)); // check that `SIZE` was correct. if (size != SIZE) { } </code></pre> <p>If not, then you need to write the data in the buffer to another file instead of accumulating it.</p> <p><strong>EDIT (SAMPLE TEST PROGRAM)</strong>:</p> <p>Here's a complete program that fetches StackOverflow's front page. This downloads about 200K of HTML code in 1K chunks and the full page is retrieved. Can you run this and see if it works?</p> <pre><code>#include &lt;Windows.h&gt; #include &lt;Wininet.h&gt; #include &lt;iostream&gt; #include &lt;fstream&gt; namespace { ::HINTERNET netstart () { const ::HINTERNET handle = ::InternetOpenW(0, INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0); if ( handle == 0 ) { const ::DWORD error = ::GetLastError(); std::cerr &lt;&lt; "InternetOpen(): " &lt;&lt; error &lt;&lt; "." &lt;&lt; std::endl; } return (handle); } void netclose ( ::HINTERNET object ) { const ::BOOL result = ::InternetCloseHandle(object); if ( result == FALSE ) { const ::DWORD error = ::GetLastError(); std::cerr &lt;&lt; "InternetClose(): " &lt;&lt; error &lt;&lt; "." &lt;&lt; std::endl; } } ::HINTERNET netopen ( ::HINTERNET session, ::LPCWSTR url ) { const ::HINTERNET handle = ::InternetOpenUrlW(session, url, 0, 0, 0, 0); if ( handle == 0 ) { const ::DWORD error = ::GetLastError(); std::cerr &lt;&lt; "InternetOpenUrl(): " &lt;&lt; error &lt;&lt; "." &lt;&lt; std::endl; } return (handle); } void netfetch ( ::HINTERNET istream, std::ostream&amp; ostream ) { static const ::DWORD SIZE = 1024; ::DWORD error = ERROR_SUCCESS; ::BYTE data[SIZE]; ::DWORD size = 0; do { ::BOOL result = ::InternetReadFile(istream, data, SIZE, &amp;size); if ( result == FALSE ) { error = ::GetLastError(); std::cerr &lt;&lt; "InternetReadFile(): " &lt;&lt; error &lt;&lt; "." &lt;&lt; std::endl; } ostream.write((const char*)data, size); } while ((error == ERROR_SUCCESS) &amp;&amp; (size &gt; 0)); } } int main ( int, char ** ) { const ::WCHAR URL[] = L"http://stackoverflow.com/"; const ::HINTERNET session = ::netstart(); if ( session != 0 ) { const ::HINTERNET istream = ::netopen(session, URL); if ( istream != 0 ) { std::ofstream ostream("output.txt", std::ios::binary); if ( ostream.is_open() ) { ::netfetch(istream, ostream); } else { std::cerr &lt;&lt; "Could not open 'output.txt'." &lt;&lt; std::endl; } ::netclose(istream); } ::netclose(session); } } #pragma comment ( lib, "Wininet.lib" ) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload