2014-12-23 47 views
2

我正在構建一個相對簡單的應用程序,要求查找目錄,檢查它們是否正確,然後刪​​除其中一個並使用另一個的內容重新創建目錄。我遇到這種怪異的行爲,我會盡力解釋:任何人都可以解釋shutil.rmtree和shutil.copytree這個奇怪的行爲嗎?

當我已經得到了目標文件夾窗口打開,它是空的,有一個拒絕訪問異常,然後我被踢出的文件夾,它被刪除。但是,如果它不是空的,它就會正常工作,沒有例外,目標目錄(從看起來看起來)被清空,然後從源目錄中填充文件。這很奇怪,因爲它應該直接刪除目標文件夾,然後使用源目標中相同的名稱和內容重新創建目標文件夾。

這沒有意義對我來說,不應該有,當我瀏覽目錄時,它不是空的,因爲當它是空的完全相同的例外呢?有什麼區別,它仍然應該只是刪除文件夾。有什麼合理的解釋嗎?另外,如果出現異常,爲什麼該目錄會被刪除呢?

代碼這個特殊的部分是相當簡單的(請記住我是一個初學者:))

def Delete(self, dest): 

    try: 
     shutil.rmtree(dest) 
     self.Paste(self.src, dest) 
    except (IOError, os.error) as e: 
     print e 

def Paste(self, src, dest): 

    try: 
     shutil.copytree(src, dest) 
    except (IOError, os.error) as e: 
     print e 
+1

您是否從Delete()或Paste()中獲取了拒絕訪問異常?很難判斷'try'塊中有多個語句。最好將整個回溯加入你的問題。一定要將它縮進4個空格,以便它可讀。 – martineau

回答

1

這是預期在Windows上的行爲。

內部shutil.rmtree調用MSDN(http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915%28v=vs.85%29.aspx)上記錄的windows API函數DeleteFile

此功能(通過我的HIGHlite)具有以下特性:

的功能的DeleteFile標誌着關閉要刪除的文件。 因此,直到該文件的最後一個句柄關閉,文件刪除纔會發生。隨後調用CreateFile打開文件失敗,並顯示ERROR_ACCESS_DENIED。

如果任何其他進程仍有打開的句柄(例如病毒掃描程序,Windows資源管理器,因爲你看目錄或其他任何可能仍然有一個手柄,該目錄),它不會消失。

通常你剛剛捕獲異常在粘貼操作,然後重試了幾次/一段dozend毫秒,處理所有那些怪異的病毒掃描程序異常。

小獎金:您可以使用WinDbg或ProcessExplorer找出誰仍保持打開的句柄到文件(只使用查找處理過程中的資源管理器和搜索文件名)。

+0

好吧,但這仍然不能解釋爲什麼當目錄不是空的時候沒有問題,這使我最困惑。再次說明:無論如何,程序都應該刪除目錄。當我在Windows資源管理器中觀看目錄時,它是空的,但有一個例外,但如果它不是空的,那麼沒有任何問題,並且我能夠看到文件被粘貼,而該文件夾應該被刪除並重新創建 – zephi

+0

嗯,這是一個競爭條件。如果這個目錄是空的,那麼你有最短的情況(只有一個'DeleteFile'),如果它不是空的,shutil代碼將遞歸地刪除大量的文件和目錄,所以explorer有更多的時間去除句柄在你的下一個'CreateFile'調用發生之前。如果你真的想知道發生了什麼,你需要使用windbg並進行一些內核級別的調試。 – schlenk

相關問題