Win 32写入文件:访问错误1784

Win 32 Writefile: Access Viloation and Error 1784

本文关键字:访问 错误 1784 文件 Win      更新时间:2023-10-16

以下代码有两个问题。首先,我一直在这个论坛和其他各种论坛上搜索1784错误代码的答案,但我所尝试的一切都失败了。我在stackoverflow上检查过的两个线程是WriteFile返回错误1784和BlockWrite I/O错误1784。我已经在这个论坛上查看了其他一些,但我不记得现在到底是什么。

我正试图将一个结构数组保存到一个空的二进制文件中。第一个问题是,如果我的大小变量(nNumberOfBytesToWrite参数)小于99000个字节,我就会发生访问冲突。这个数字跳来跳去。有一段时间,当我测试它时,如果它是99999字节,但不是100000字节,就会有访问冲突。当然,我最终想要做的是将大小设置为整个数组的大小。要处理的原始代码现在被注释掉了,所以我可以用各种大小进行测试。

发生的第二件事(如果我没有遇到访问冲突)是我得到错误代码1784,每次WriteFile都会失败。正如这个主题上的其他线程所说,这在MSDN上被定义为ERROR_INVALID_USER_BUFFER,描述为"提供的用户缓冲区对请求的操作无效"(http://msdn.microsoft.com/en-us/library/windows/desktop/bb540534%28v=vs.85%29.aspx)并根据他们的代码尝试了一些变体,但似乎什么都不起作用。

这个问题可能非常棘手,我相信我忽略了一些简单得离谱的事情,但如果有人有建议,我们将不胜感激。

case IDM_SAVE1:
{
HANDLE hFile = CreateFile("MineSave.mss", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
int test_buffer[] = {1,2,3,4,5,6,7,8,9,10};
if(hFile != INVALID_HANDLE_VALUE)
{
BOOL bSuccess;
DWORD size = 100000; //DWORD size = (((sizeof(tile)) * tiles_total));
LPDWORD bytes_written = 0;
bSuccess = WriteFile(hFile, test_buffer, size, bytes_written, NULL);
if(bSuccess)
{
MessageBox(hwnd, "File saved successfully.", "Great Job!", MB_OK);
}
else
{
DWORD error = GetLastError();
MessageBox(hwnd, "Could not write to file.", "Error", MB_OK);
}
CloseHandle(hFile);
}
else
{
MessageBox(hwnd, "Could not create file.", "Error", MB_OK);
}
}
break;

您的缓冲区大小为10 int,在Windows上为40字节。您正试图从该缓冲区写入100000字节。这是未定义的行为,缓冲区溢出。因此出现了访问违规。

不能将大于sizeof(test_buffer)的值(即40)传递给WriteFilenNumberOfBytesToWrite参数。

您需要在循环中写入此文件,每次写入40个字节,直到您写入所需的内容为止。也许是这样的:

BOOL bSuccess = TRUE;
DWORD bytesRemaining = 100000;
while (bSuccess && bytesRemaining>0)
{
DWORD bytesToWrite = std::min(sizeof(test_buffer), bytesRemaining);
DWORD bytesWritten;
bSuccess = WriteFile(hFile, test_buffer, bytesToWrite, &bytesWritten, NULL);
bytesRemaining -= bytesToWrite;
}
if (!bSuccess)
{
//handle error;
}

一次写入40个字节相当慢。您会发现,每次调用WriteFile时写几个KB会更高效。

请注意,如果您也像这里所做的那样将NULL传递给lpOverlapped,则不允许将NULL传递给lpNumberOfBytesWritten参数。来自文件:

lpNumberOfBytesWritten[out,可选]

只有当lpOverlapped参数不为NULL时,此参数才能为NULL。

必须提供一个缓冲区来接收写入的字节数,lpNumberOfBytesWritten参数必须非NULL,或者lpOverlapped参数必须非空。

您正在为两者传递NULL,这是非法的,并导致访问冲突。