如果(理论上)我应该被允许,为什么我不能打开文件进行阅读?

时间:2012-05-06 19:18:06

标签: c winapi file-io

我在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的重点是允许其他线程/进程打开一个文件,只是为了阅读而不管它是否已经打开。

有人可以帮我解决这个问题吗?

P.S。如果文件是邮件邮件,那会有什么不同吗?

3 个答案:

答案 0 :(得分:7)

您的CreateFile()调用显式拒绝写共享,您指定了FILE_SHARE_READ。这不起作用,第一个程序已经获得了写访问权,因为它使用了GENERIC_WRITE。您无法拒绝已获得的权利,因此呼叫将因共享违规错误而失败。

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

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

答案 1 :(得分:2)

  

您无法请求与指定的访问模式冲突的共享模式   在具有打开句柄的现有请求中。 CreateFile会失败而且   GetLastError函数将返回ERROR_SHARING_VIOLATION。

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

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

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

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

答案 2 :(得分:1)

我认为CreateFile文档中的答案是:

  

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

即。你打开文件写,但你没有表明这个写可以共享。