gpt4 book ai didi

c++ - InternetReadFile 填充缓冲区,但返回读取的零字节

转载 作者:可可西里 更新时间:2023-11-01 10:14:53 28 4
gpt4 key购买 nike

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

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) %s\r\n"), 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 变量来围绕此特定情况编写代码,但这只是临时解决方法过了这个错误,我真的需要了解为什么会出现这个问题。

这个错误的后果(没有我的软糖)是数据被丢弃,我最终得到一个缺少第一个 block 但其他方面完全正确的文件。因此 MD5 检查失败,我丢失了文件的第一部分。

我只是碰巧知道文件总是大于我正在使用的 block 大小,所以我的软糖会起作用,但我不喜欢在代码中使用这些不需要的可怕变通方法.

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

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

非常感谢,安德鲁

最佳答案

机器实际上磁盘空间用完了吗? InternetReadFile 默认会在你背后写入磁盘:

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. This is especially important if the requested data is written to the cache, because otherwise the cache will not be properly updated and the file downloaded will not be committed to the cache. Note that caching happens automatically unless the original request to open the data stream set the INTERNET_FLAG_NO_CACHE_WRITE flag.

关于c++ - InternetReadFile 填充缓冲区,但返回读取的零字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43283091/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com