python 中有許多「開蓋即食」的模塊(比如 os,subprocess 和 shutil)以支持文件 I/O 操作。在這篇文章中,你將會看到一些用 Python 實現文件複製的特殊方法。下面我們開始學習這九種不同的方法來實現 Python 複製文件操作。
在開始之前,你必須明白為什麼了解最適合你的 Python 複製文件方法是如此重要。這是因為文件 I/O 操作屬於 性能密集型 而且 經常會達到瓶頸 。這就是為什麼你應該根據你的應用程式的設計選擇最好的方法。
一些共享資源的程序會傾向於以阻塞模式來複製文件,而有些則可能希望以異步方式執行。比如 — 使用線程來複製文件或者啟動單獨的進程來實現它。還有一點需要考慮的是平臺的可移植性。這意味著你應該知道你要運行的程序所在的目標作業系統(Windows/Linux/Mac OS X 等)。
用 Python 複製文件的 9 種方法具體是:
1.Shutil Copyfile()方法只有當目標是可寫的,這個方法才會將源內容複製到目標位置。如果你沒有寫入權限,則會導致 IOError 異常。
它會打開輸入文件進行讀取並忽略其文件類型。接下來,它不會以任何不同的方式處理特殊文件,也不會將它們複製為新的特殊文件。
Copyfile() 方法使用下面的低級函數 copyfileobj()。它將文件名作為參數,打開它們並將文件句柄傳遞給 copyfileobj()。這個方法中有一個可選的第三個參數,你可用它來指定緩衝區長度。然後它會打開文件並讀取指定緩衝區大小的塊。但是,默認是一次讀取整個文件。
以下是關於 copyfile() 方法的要點。
它將源內容複製到目標文件中。
如果目標文件不可寫入,那麼複製操作將導致 IOError 異常。
如果源文件和目標文件都相同,它將會返回 SameFileError。
但是,如果目標文件之前有不同的名稱,那麼該副本將會覆蓋其內容。
如果目標是一個目錄,這意味著此方法不會複製到目錄,那麼會發生 Error 13。
它不支持複製諸如字符或塊驅動以及管道等文件。
2.Shutil Copy()方法copy() 方法的功能類似於 Unix 中的「cp」命令。這意味著如果目標是一個文件夾,那麼它將在其中創建一個與源文件具有相同名稱(基本名稱)的新文件。此外,該方法會在複製源文件的內容後同步目標文件權限到源文件。
copy() 還可以在複製內容時設置權限位,而 copyfile() 只複製數據。
如果目標是目錄,則 copy() 將複製文件,而 copyfile() 會失敗,出現 Error 13。
有趣的是,copyfile() 方法在實現過程中使用 copyfileobj() 方法,而 copy() 方法則是依次使用 copyfile() 和 copymode() 函數。
在 Potion-3 可以很明顯看出 copyfile() 會比 copy() 快一點,因為後者會有一個附加任務(保留權限)。
3.Shutil Copyfileobj()方法該方法將文件複製到目標路徑或者文件對象。如果目標是文件對象,那麼你需要在調用 copyfileobj() 之後關閉它。它還假定了一個可選參數(緩衝區大小),你可以用來設置緩衝區長度。這是複製過程中保存在內存中的字節數。系統使用的默認大小是 16KB。
4.Shutil Copy2()方法雖然 copy2() 方法的功能類似於 copy()。但是它可以在複製數據時獲取元數據中添加的訪問和修改時間。複製相同的文件會導致 SameFileError 異常。
copy() vs copy2() :copy() 只能設置權限位,而 copy2() 還可以使用時間戳來更新文件元數據。
copy() 在函數內部調用 copyfile() 和 copymode(), 而 copy2() 是調用 copystat() 來替換copymode()。
5.Os Popen()方法該方法創建一個發送或者接受命令的管道。它返回一個打開的並且連接管道的文件對象。你可以根據文件打開模式將其用於讀取或者寫入比如『r』(默認)或者『w』。
mode – 它可以是『r』(默認)或者『w』
Bufsize – 如果它的值是0,那麼就不會出現緩衝。如果將它設置為1,那麼在訪問文件時就會發生行緩衝。如果你提供一個大於1的值,那麼就會在指定緩衝區大小的情況下發生緩衝。但是,對於負值,系統將採用默認緩衝區大小。
6.Os System()方法這是運行任何系統命令的最常用方式。使用 system() 方法,你可以調用 subshell 中的任何命令。在內部,該方法將調用 C 語言的標準庫函數。
該方法返回該命令的退出狀態。
對於 Windows 系統:
對於 Liunx 系統:
7.使用異步方式的線程庫複製文件如果你想以異步方式複製文件,那麼使用下面的方法。在這裡,我們使用 Python 的線程模塊在後臺進行複製操作。
在使用這種方法時,請確保使用鎖定以避免鎖死。如果你的應用程式使用多個線程讀取/寫入文件,就可能會遇到這種情況。
8.使用Subprocess的Call()方法複製文件Subprocess 模塊提供了一個簡單的接口來處理子進程。它讓我們能夠啟動子進程,連接到子進程的輸入/輸出/錯誤管道,並檢索返回值。
subprocess 模塊旨在替換舊版模塊和函數,比如 – os.system, os.spawn*, os.popen*, popen2.*
它使用 call() 方法調用系統命令來執行用戶任務。
9.使用 subprocess 中的 Check_output() 方法複製文件使用 subprocess 中的 Check_output() 方法,你可以運行外部命令或程序並捕獲其輸出。它也支持管道。