【发布时间】:2014-12-29 10:42:09
【问题描述】:
我有几个进程尝试读取和写入同一个文件。我希望他们每个人都锁定文件,以便一次只有一个人可以访问它。
我试过这个(编辑:这次是完整的测试代码):
#include "stdafx.h"
#include "Windows.h"
bool test()
{
const char* path = "test.txt";
HANDLE hFile = CreateFileA(path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("ERROR: Cannot open file %s\n", path);
return false;
}
// Lock the file
{
OVERLAPPED overlapped = {0};
BOOL res = LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, ~0, ~0, &overlapped);
if (!res)
{
printf("ERROR: Cannot lock file %s\n", path);
return false;
}
}
DWORD fileSize = GetFileSize(hFile, NULL);
if (fileSize > 0)
{
char* content = new char[fileSize+1];
// Read the file
BOOL res = ReadFile(hFile, content, fileSize, NULL, NULL);
if (!res)
{
printf("ERROR: Cannot read file %s\n", path);
}
delete[] content;
}
const char* newContent = "bla";
int newContentSize = 3;
// Write the file
BOOL res = WriteFile(hFile, newContent, newContentSize, NULL, NULL);
if (!res)
{
//int err = GetLastError();
printf("ERROR: Cannot write to file\n");
}
// Unlock the file
{
OVERLAPPED overlapped = {0};
UnlockFileEx(hFile, 0, ~0, ~0, &overlapped);
}
CloseHandle(hFile);
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
bool res = test();
return 0;
}
这在装有 Windows 8 的计算机上运行良好。但在装有 Windows 7 的同事的计算机上,它崩溃了。具体来说,对 ReadFile 和 WriteFile 的调用总是会崩溃。
请注意,它永远不会进入带有错误 printfs 的代码路径。除了在 ReadFile 中的位置 0x00000000 写入之外,此代码不会触发任何错误(在 Windows 7 上运行时)。
我们还尝试将重叠的结构体传递给 ReadFile 和 WriteFile 调用。它可以防止崩溃但锁不再起作用,文件全部加扰(不是用这个测试代码,用真实代码)。
我做错了什么?
【问题讨论】:
-
不检查返回结果和GetLastError()。
-
包括完整的代码并且是具体的。它在
ReadFile或WriteFile上崩溃?它不能同时崩溃。 -
@RichardCritten 我没有在这里包含它,但我确实检查了返回结果。在 Windows 8 上,没有错误。我正在再次检查 Window 7 以确保。
-
@Rohan 如果我评论对 ReadFile 的调用,它会在 WriteFile 中崩溃。我将尝试制作一个最小的重现代码。
-
“崩溃”不是合适的错误描述。此外,正如 Richard 所建议的,如果函数的文档表明您需要,请在调用失败后检查
GetLastError()。