documentationには、以下の発言を作る:
InternetReadFileをはいくつかの例外を除いて、多くのベースのReadFile関数と同じように動作します。通常、InternetReadFileはHINTERNETハンドルからのデータをバイトの連続したストリームとして取得します。 InternetReadFileへの各呼び出しで読み取るデータの量は、dwNumberOfBytesToReadパラメーターで指定され、データはlpBufferパラメーターで返されます。通常の読み取りでは、ファイルの最後に達するまで、InternetReadFileへの呼び出しごとに指定されたdwNumberOfBytesToReadを取得します。 すべてのデータが確実に取得されるようにするには、関数がTRUEを返し、lpdwNumberOfBytesReadパラメータがゼロに等しくなるまで、アプリケーションはInternetReadFile関数を呼び出し続けなければなりません。
基本的には、正確にdwNumberOfBytesToRead
を読み取る機能は保証されません。 lpdwNumberOfBytesRead
パラメータを使用して実際に読み取られたバイト数を確認します。
さらに、合計ファイルサイズがdwNumberOfBytesToRead
より大きいとすぐに、呼び出しを複数回呼び出す必要があります。これは一度にdwNumberOfBytesToRead
以上を読み取ることができないためです。その後、あなたはそれを蓄積するのではなく、別のファイルにバッファ内のデータを記述する必要がある、
::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, &read);
if (result == FALSE) {
error = ::GetLastError();
}
}
while ((error == ERROR_SUCCESS) && (read > 0) && ((size+=read) < SIZE));
// check that `SIZE` was correct.
if (size != SIZE) {
}
ない場合:あなたは、事前に合計ファイルサイズを持っている場合は
は、ループは次の形式を取ります。
EDIT(サンプルテストプログラム):
はここにStackOverflowのフロントページを取得し、完全なプログラムです。これにより、約200KのHTMLコードが1Kチャンクでダウンロードされ、全ページが取得されます。あなたはこれを実行し、それが動作するかどうか見ることができますか?
#include <Windows.h>
#include <Wininet.h>
#include <iostream>
#include <fstream>
namespace {
::HINTERNET netstart()
{
const ::HINTERNET handle =
::InternetOpenW(0, INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0);
if (handle == 0)
{
const ::DWORD error = ::GetLastError();
std::cerr
<< "InternetOpen(): " << error << "."
<< std::endl;
}
return (handle);
}
void netclose (::HINTERNET object)
{
const ::BOOL result = ::InternetCloseHandle(object);
if (result == FALSE)
{
const ::DWORD error = ::GetLastError();
std::cerr
<< "InternetClose(): " << error << "."
<< 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
<< "InternetOpenUrl(): " << error << "."
<< std::endl;
}
return (handle);
}
void netfetch (::HINTERNET istream, std::ostream& ostream)
{
static const ::DWORD SIZE = 1024;
::DWORD error = ERROR_SUCCESS;
::BYTE data[SIZE];
::DWORD size = 0;
do {
::BOOL result = ::InternetReadFile(istream, data, SIZE, &size);
if (result == FALSE)
{
error = ::GetLastError();
std::cerr
<< "InternetReadFile(): " << error << "."
<< std::endl;
}
ostream.write((const char*)data, size);
}
while ((error == ERROR_SUCCESS) && (size > 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 << "Could not open 'output.txt'." << std::endl;
}
::netclose(istream);
}
::netclose(session);
}
}
#pragma comment (lib, "Wininet.lib")
私の答えは完全な作業プログラムが含まれています。あなたはそれを試して、それが動作するかどうか見ることができますか? –