InternetReadFile 填充缓冲区,但返回零字节读取



我在尝试从互联网下载为 Windows Compact 2013 编写的C++应用程序中的文件时遇到了一个非常奇怪的问题。

BOOL WWW::Read(char* buffer, DWORD buffer_size)
{
memset(buffer, 0, buffer_size);
m_dwBytesRead = 0;
BOOL bResult = InternetReadFile(m_handle, buffer, buffer_size, &m_dwBytesRead);
if (!bResult)
{
DWORD dwLastError = GetLastError();
TCHAR *err;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPTSTR)&err, 0, NULL))
{
LOGMSG(1, (TEXT("InternetReadFile failed at - (%u) %srn"), dwLastError, err));
LocalFree(err);
}
}
// FUDGE
if (m_dwBytesRead == 0)
{
DWORD dwZeros = countZeros(buffer, buffer_size);
if (dwZeros < buffer_size)
{
m_dwBytesRead = buffer_size;
}
}
// END OF FUDGE
return bResult;
}

我从另一个成员函数反复调用上述函数,如下所示

DWORD dwWritten;
while (!(Read(buffer, DOWNLOAD_BUFFER_SIZE) && m_dwBytesRead == 0))
{
WriteFile(m_hDownload, buffer, m_dwBytesRead, &dwWritten, NULL);
m_dwActualSize += dwWritten;
++m_dwChunks;
if (m_dwBytesRead > 0)
m_dwInactivity = 0;
else if (++m_dwInactivity > INACTIVITY_LIMIT)
return WDS_INACTIVITY;
}

如果没有 FUDGE,此函数在第一次通过时失败,并在后续调用中正常工作。我在第一次通过此函数调用时收到的错误是

InternetReadFile failed at - (112) There is not enough space on the disk.

我不明白为什么在读取操作期间应该收到"磁盘空间不足"错误。我已经检查了缓冲区是否已分配且可用,并且与预期大小匹配。事实上,当我检查缓冲区的内容时,我发现它已被填充了预期的字节数,但是m_dwBytesRead变量的内容仍设置为 0。

如您所见,我试图通过检查缓冲区的内容以查看它是否已填充,然后捏造m_dwBytesRead变量来解决此特定情况,但这只是让我克服此错误的临时解决方法,我真的需要了解为什么会出现此问题。

这个错误的后果(没有我的捏造)是数据被扔掉了,我最终得到一个缺少第一个块但其他方面完全正确的文件。因此,MD5 检查失败,并且我缺少文件的第一部分。

我只是碰巧知道该文件将始终大于我正在使用的块大小,所以我的软糖会起作用,但我不喜欢在不需要的时候在代码中使用这些可怕的解决方法。

如果有人能阐明导致问题的原因,将不胜感激。

我使用的是Visual Studio 2013 C++(本机Windows应用程序,而不是MFC),目标是32位和Unicode,运行在Windows Compact 2013上。

非常感谢, 安德鲁

计算机是否真的磁盘空间不足? 默认情况下,InternetReadFile将在您背后写入磁盘:

为了确保检索所有数据,应用程序必须继续调用 InternetReadFile 函数,直到该函数返回 TRUE 并且 lpdwNumberOfBytesRead 参数等于零。如果将请求的数据写入缓存,这一点尤其重要,因为否则缓存将无法正确更新,下载的文件将不会提交到缓存。请注意,缓存会自动发生,除非打开数据流的原始请求设置了INTERNET_FLAG_NO_CACHE_WRITE标志

最新更新