2

我在 C 中有两个项目:

首先:

include windows.h
include stdio.h
include tchar.h

int main()
{
     HANDLE hFile = CreateFile("D:\\f.txt",
    GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

    if(hFile == INVALID_HANDLE_VALUE)
        _tprintf("Error: CreateFile %d\n",GetLastError());

    Sleep(5000);

    return 0;
}

第二:

include windows.h
include stdio.h
include tchar.h

int main()
{
     HANDLE hFile = CreateFile("D:\\f.txt",
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

if(hFile == INVALID_HANDLE_VALUE)
    _tprintf("Error: CreateFile %d\n",GetLastError());

            return 0;
}

第一个程序应该打开文件进行读取,同时允许其他人从中读取。第二个应该打开文件进行阅读。

当我运行程序时,第二个给我错误 32 (ERROR_SHARING_VIOLATION)。

我认为 FILE_SHARE_READ 的全部意义在于允许其他线程/进程打开一个文件只是为了读取,无论它是否已经打开。

谁能帮我解决这个问题?

PS如果文件是一个邮槽,那会有什么不同吗?

4

3 回答 3

8

您的 CreateFile() 调用明确拒绝写入共享,您指定了 FILE_SHARE_READ。那行不通,因为第一个程序使用了 GENERIC_WRITE,所以它已经获得了写访问权限。您不能拒绝已获得的权限,因此调用将失败并出现共享冲突错误。

为了使它工作,第二个调用必须指定 FILE_SHARE_WRITE 代替。并处理试图从在不可预测的时间和地点写入的文件中读取的头痛问题。这通常只有在第一个进程只附加到文件并且不查找时才会有一个好的结果。而且您有时会正确处理仅获取部分附加数据,因为其中一些仍停留在缓冲区中或正在写入的过程中。棘手的东西。如果有问题,请考虑在消息模式下使用管道。

从评论中重申,共享标志不控制可以做什么,它们控制另一个进程可以对文件做什么。您想要做什么在第二个参数中指定。所以缺少 FILE_SHARE_WRITE 是问题所在,因为它阻止了另一个进程写入文件。但它已经做到了。

于 2012-05-06T19:45:04.737 回答
3

您不能请求与具有打开句柄的现有请求中指定的访问模式冲突的共享模式。CreateFile 将失败,GetLastError 函数将返回 ERROR_SHARING_VIOLATION。

在第一个程序中,您将第三个参数 (dwShareMode) 指定为授予其他进程“读取”权限,并在第二个参数 (dwDesiredAccess) 中为其自身请求“写入”访问权限。

然后在第二个程序中,您在第二个参数中请求“读取”访问权限(这很好)并在第三个参数中仅授予其他进程“读取”权限,这与第一个程序中指定的访问模式冲突(“写”)。第一个程序打开文件是“具有打开句柄的现有请求”。

在第一个程序中,您说“我可以写入“f.txt”。其他人只能读取它。” 而在第二个程序中,您说“我可以阅读“f.txt”。其他人只能阅读它。”,这是一个矛盾,因为第一个程序已经在写入“f.txt”。

正如已经提到的,由两个不同的进程同时读取和写入文件是数据损坏的好方法。

于 2012-05-07T18:09:00.923 回答
1

我认为CreateFile文档中的答案:

您不能请求与具有打开句柄的现有请求中指定的访问模式冲突的共享模式。CreateFile 将失败,GetLastError 函数将返回 ERROR_SHARING_VIOLATION。

即您打开要写入的文件,但您没有表明可以共享此写入。

于 2012-05-06T19:22:32.523 回答