我对WinInet 的 InternetReadFile (C++) 有疑问。
在极少数情况下,函数会失败,GetLastError 返回上述错误0x8007007a(根据 ErrorLookup 对应于“传递给系统调用的数据区域太小”)。
我对此有几个问题:
- 为什么在极少数情况下会发生这种情况,但在其他情况下却可以正常工作(我当然是在谈论总是下载相同的 ~15MB zip 文件)?
- 这真的与传递给 API 调用的缓冲区大小有关吗?我为此调用使用了 1024 BYTES 的 const 缓冲区大小。我应该使用更大的缓冲区大小吗?如果是这样,我怎么知道“正确”的缓冲区大小是多少?
- 如果我确实收到此错误,我该怎么做才能在运行时恢复?
添加代码片段(请注意,这不会按原样工作,因为需要一些初始化代码):
#define HTTP_RESPONSE_BUFFER_SIZE 1024
std::vector<char> responseBuffer;
DWORD dwResponseBytesRead = 0;
do
{
const size_t oldBufferSize = responseBuffer.size();
responseBuffer.resize(oldBufferSize + HTTP_RESPONSE_BUFFER_SIZE);
// Now we read again to the last place we stopped
// writing in the previous iteration.
dwResponseBytesRead = 0;
BOOL bInternetReadFile = ::InternetReadFile(hOpenRequest, // hFile. Retrieved from a previous call to ::HttpOpenRequest
(LPVOID)&responseBuffer[oldBufferSize], // lpBuffer.
HTTP_RESPONSE_BUFFER_SIZE, // dwNumberOfBytesToRead.
&dwResponseBytesRead); // lpdwNumberOfBytesRead.
if(!bInternetReadFile)
{
// Do clean up and exit.
DWORD dwErr = ::GetLastError(); // This, in some cases, will return: 0x7a
HRESULT hr = HRESULT_FROM_WIN32(dwErr); // This, in some cases, will return: 0x8007007a
return;
}
// Adjust the buffer according to the actual number of bytes read.
responseBuffer.resize(oldBufferSize + dwResponseBytesRead);
}
while(dwResponseBytesRead != 0);