Win32写文件:访问冲突和错误1784

时间:2012-09-28 16:01:42

标签: c++ winapi

以下代码存在两个问题。首先,我一直在搜索这个以及其他各种论坛以获取我的1784错误代码的答案,而我尝试过的所有内容都失败了。我在stackoverflow上检查过的两个线程是WriteFile returning error 1784BlockWrite I/O Error 1784。我在这个论坛上检查了一些其他人,但我不记得现在究竟是什么。

我正在尝试将结构数组保存到空的二进制文件中。第一个问题是,如果我的大小变量(nNumberOfBytesToWrite参数)小于99000字节,则会出现访问冲突。那个号码跳了起来。在我测试的一段时间内,如果它是99,999字节而不是100,000字节,则会有访问冲突。当然,我最终想要做的是将大小设置为整个数组的大小。处理它的原始代码现已注释掉,因此我可以测试各种尺寸。

发生的第二件事(如果我没有获得访问冲突)是我得到错误代码1784并且WriteFile每次都失败。正如本主题中的其他线程所述,这在MSDN上定义为ERROR_INVALID_USER_BUFFER,描述为“提供的用户缓冲区对请求的操作无效”。我已经查看了MSDN自己打开这样的文件(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;

2 个答案:

答案 0 :(得分:7)

您的缓冲区大小为10个整数,在Windows上为40个字节。您正在尝试从该缓冲区写入100,000个字节。这是未定义的行为,缓冲区溢出。因此违反了访问权限。

您不得将大于sizeof(test_buffer)的值(即40)传递给nNumberOfBytesToWrite的{​​{1}}参数。

您需要在循环中编写此文件,一次写入40个字节,直到您根据需要编写。也许是这样的:

WriteFile

一次写入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; } 时,您都会发现写几KB的效率更高。

请注意,如果您也将WriteFile传递给NULL,则不允许您将lpNumberOfBytesWritten传递给NULL参数。来自documentation

  

lpNumberOfBytesWritten [out,optional]

     

...

     

仅当lpOverlapped参数不为NULL时,此参数才为NULL。

答案 1 :(得分:1)

必须提供缓冲区来接收写入的字节数,lpNumberOfBytesWritten参数必须为非NULL,或lpOverlapped参数必须为非NULL

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