【问题标题】:CreateFile fails with error ERROR_SHARING_VIOLATIONCreateFile 失败并出现错误 ERROR_SHARING_VIOLATION
【发布时间】:2011-05-25 00:44:35
【问题描述】:

我正在使用 CreateFile api,有时它会随机失败并出现错误:ERROR_SHARING_VIOLATION。

我用谷歌搜索过,几乎没有关于这个错误的信息。奇怪的是下次打开同一个文件还挺开心的。

这是我的代码:

void FileHandle::open(const char* fileName, FILE_MODE mode)
{
    if (m_bIsOpen)
        close();

    HANDLE fh = NULL;

    DWORD dwDesiredAccess  = GENERIC_READ;
    DWORD dwShareMode = FILE_SHARE_READ;
    DWORD dwCreationDisposition = OPEN_EXISTING;

    switch (mode)
    {
    case FILE_READ:
        break;

    case FILE_WRITE:
        dwDesiredAccess  = GENERIC_WRITE;
        dwShareMode = 0;
        dwCreationDisposition = CREATE_ALWAYS;
        break;

    case FILE_APPEND:
        dwDesiredAccess  = GENERIC_WRITE;
        dwShareMode = 0;
        dwCreationDisposition = OPEN_ALWAYS;
        break;

    default:
        throw gcException(ERR_INVALID, "The mode was invalid");
        break;
    }

    fh = CreateFile(fileName, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL);

    if (!fh || fh == INVALID_HANDLE_VALUE)
        throw gcException(ERR_INVALIDFILE, GetLastError(), gcString("Failed to open the file {0}", fileName));

    m_hFileHandle = fh;
    m_bIsOpen = true;

    if (mode == FILE_APPEND)
    {
        DWORD high = 0;
        DWORD low = GetFileSize(fh, &high);

        uint64 pos = (((uint64)high)<<32) + (uint64)low;
        seek(pos);
    }
}

是我做错了什么还是 api 有问题?

编辑: 我使用完整的文件名(即 C:\somefile.txt)和 mode=FILE_WRITE

【问题讨论】:

  • 调用失败时运行哪种情况?此外,您应该只检查文件句柄是否等于 INVALID_HANDLE_VALUE,不要检查它是否为 NULL。另外请在 throw 之前移动 GetLastError 调用并将其存储在 DWORD 中。
  • 如果我检查它是否为 NULL 也没关系,错误代码是 32(认为我弄混了,应该是 ERROR_SHARING_VIOLATION)。
  • 使用进程监视器 (technet.microsoft.com/en-us/sysinternals/bb896645) 并为您打开的文件的路径设置过滤器。检查是否没有其他进程(例如反恶意软件、桌面搜索、备份)正在打开它。

标签: c++ winapi file


【解决方案1】:

CreateFile 没有任何问题 - 共享冲突意味着其他东西打开了相同的文件。可能是你自己的程序,如果你以共享模式0打开文件,你将无法再次打开它。

当您收到错误时,您可以使用Process Explorer 来确定哪些进程打开了文件。

【讨论】:

  • 它正在创建一个以前从未存在过的新文件,此时没有其他文件具有新文件的名称(它是一个图像缓存存储)。
  • 刚刚发现我的一部分代码在两个不同的线程中两次下载同一个图像,因此第一个线程会打开文件,第二个线程会死。
【解决方案2】:

机器上有杀毒软件吗?有时,AV(或其他监视文件的软件)的操作和计时可能会导致共享冲突。

如果您要打开现有文件以进行独占访问,则尤其如此(如果文件已存在,则FILE_WRITEFILE_APPEND 情况就是这种情况)。

【讨论】:

  • 无影音。大约每 20 次发生 1 次
【解决方案3】:

我的意思不是不尊重,但我上周刚刚在类似的事情上朝自己的脚开枪:

确定没有其他文件以阻止请求访问的方式打开文件吗?

在我的例子中,我在 Linux 命令窗口中使用 ctrl-Z 来暂停一个创建套接字连接的程序,然后我就去睡觉了。第二天早上,经过一些简单的更改后,我在运行程序时不断收到“无法创建套接字:正在使用的服务”消息。可悲的是,我花了几个小时调试我损坏的东西。一旦我杀死了有问题的暂停进程,它就可以正常工作了。

【讨论】:

    【解决方案4】:

    微软说here 这可能会发生,并且它取决于应用程序在它发生时重试。可怕,但你去吧。

    【讨论】:

    • 鼓励链接到外部资源,但请在链接周围添加上下文,以便您的其他用户了解它是什么以及为什么存在。始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。
    • web.archive.org/web/20150328004214/https://… 仍然提供链接。总结:唯一的原因是文件已经被打开(但没有共享给其他人打开)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2012-09-24
    • 2013-07-18
    • 2021-10-12
    • 2020-10-23
    • 2020-07-20
    相关资源
    最近更新 更多