2010-12-14 172 views
3

我使用CreateFile api,有時候它會隨機失敗,錯誤:ERROR_SHARING_VIOLATION。CreateFile失敗,錯誤ERROR_SHARING_VIOLATION

我已經用Google搜索了,這個錯誤幾乎沒有。奇怪的是,下次打開同一個文件也很開心。

這裏是我的代碼:

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)和模式= FILE_WRITE

+0

呼叫失敗時會運行哪種情況?你也應該只在文件句柄等於INVALID_HANDLE_VALUE時檢查,不檢查它是否爲NULL。還請在拋出之前移動GetLastError調用並將其存儲在DWORD中。 – 2010-12-14 02:06:39

+0

無關緊要,如果我檢查它對NULL,錯誤代碼是32(認爲我混淆了,應該是ERROR_SHARING_VIOLATION)。 – Lodle 2010-12-14 02:13:11

+0

使用進程監視器(http://technet.microsoft.com/en-us/sysinternals/bb896645)併爲要打開的文件的路徑設置篩選器。檢查是否沒有其他進程(例如反惡意軟件,桌面搜索,備份)正在打開它。 – 2010-12-14 02:48:22

回答

6

CreateFile沒有什麼問題 - 共享衝突意味着別的文件打開了相同的文件。這可能是你自己的程序,如果你打開文件的共享模式爲0,你將無法再打開它。

當您收到錯誤時,您可以使用Process Explorer來確定文件打開的進程。

+0

它創建一個以前從未存在的新文件,而此時沒有其他文件具有新文件的名稱(其圖像緩存存儲)。 – Lodle 2010-12-14 02:40:45

+1

剛剛發現我的代碼的一部分是在兩個不同的線程中兩次下載相同的圖像,因此第一個線程將打開文件,第二個線程將死亡。 – Lodle 2010-12-14 02:50:33

1

是否有抗病毒的機器上?有時,AV(或其他監視文件的軟件)操作和時間可能會導致共享衝突。

如果您打開現有文件以進行獨佔訪問,則尤其如此(如果該文件已存在,則爲FILE_WRITEFILE_APPEND情況就是這種情況)。

+0

沒有av。每20次會發生約1次 – Lodle 2010-12-14 02:25:50

1

我的意思是不尊重,但我只拍自己在上週的腳類似的東西:

肯定沒有別的被請求的方式這將阻止訪問打開的文件?

在我的情況下,我在Linux命令窗口中使用了ctrl-Z來掛起創建套接字連接的程序,然後我去睡覺了。第二天早上經過幾次簡單的修改,我在運行程序時一直「無法創建socket:service in use」消息。可悲的是,我花了幾個小時來調試我所損壞的東西。一旦我殺死了有問題的暫停進程,它運行良好。

0

微軟說here這種情況可能發生,它可以在應用程序重新啓動時執行。可怕的,但你去了。

+0

鼓勵與外部資源的鏈接,但請在鏈接的周圍添加上下文,以便您的同行用戶瞭解它是什麼以及它爲什麼在那裏。如果目標網站無法訪問或永久離線,請始終引用重要鏈接中最相關的部分。 – 2015-04-22 09:42:33