Python 中有許多“開蓋即食”的模塊(比如 os,subprocess 和 shutil)以支持文件 I/O 操作。在這篇文章中,你將會(huì)看到一些用 Python 實(shí)現(xiàn)文件復(fù)制的特殊方法。下面我們開始學(xué)習(xí)這九種不同的方法來實(shí)現(xiàn) Python 復(fù)制文件操作。
在開始之前,你必須明白為什么了解最適合你的 Python 復(fù)制文件方法是如此重要。這是因?yàn)槲募?I/O 操作屬于性能密集型而且經(jīng)常會(huì)達(dá)到瓶頸。這就是為什么你應(yīng)該根據(jù)你的應(yīng)用程序的設(shè)計(jì)選擇最好的方法。
一些共享資源的程序會(huì)傾向于以阻塞模式來復(fù)制文件,而有些則可能希望以異步方式執(zhí)行。比如 — 使用線程來復(fù)制文件或者啟動(dòng)單獨(dú)的進(jìn)程來實(shí)現(xiàn)它。還有一點(diǎn)需要考慮的是平臺(tái)的可移植性。這意味著你應(yīng)該知道你要運(yùn)行的程序所在的目標(biāo)操作系統(tǒng)(Windows/Linux/Mac OS X 等)。
用 Python 復(fù)制文件的 9 種方法具體是:
shutil copyfile() 方法
shutil copy() 方法
shutil copyfileobj() 方法
shutil copy2() 方法
os popen 方法
os system() 方法
subprocess call() 方法
subprocess check_output() 方法
Shutil Copyfile()方法
只有當(dāng)目標(biāo)是可寫的,這個(gè)方法才會(huì)將源內(nèi)容復(fù)制到目標(biāo)位置。如果你沒有寫入權(quán)限,則會(huì)導(dǎo)致 IOError 異常。
它會(huì)打開輸入文件進(jìn)行讀取并忽略其文件類型。接下來,它不會(huì)以任何不同的方式處理特殊文件,也不會(huì)將它們復(fù)制為新的特殊文件。
Copyfile() 方法使用下面的低級(jí)函數(shù) copyfileobj()。它將文件名作為參數(shù),打開它們并將文件句柄傳遞給 copyfileobj()。這個(gè)方法中有一個(gè)可選的第三個(gè)參數(shù),你可用它來指定緩沖區(qū)長度。然后它會(huì)打開文件并讀取指定緩沖區(qū)大小的塊。但是,默認(rèn)是一次讀取整個(gè)文件。
copyfile(source_file, destination_file)
以下是關(guān)于 copyfile() 方法的要點(diǎn)。
它將源內(nèi)容復(fù)制到目標(biāo)文件中。
如果目標(biāo)文件不可寫入,那么復(fù)制操作將導(dǎo)致 IOError 異常。
如果源文件和目標(biāo)文件都相同,它將會(huì)返回 SameFileError。
但是,如果目標(biāo)文件之前有不同的名稱,那么該副本將會(huì)覆蓋其內(nèi)容。
如果目標(biāo)是一個(gè)目錄,這意味著此方法不會(huì)復(fù)制到目錄,那么會(huì)發(fā)生 Error 13。
它不支持復(fù)制諸如字符或塊驅(qū)動(dòng)以及管道等文件。
# Python Copy File - Sample Code from shutil import copyfile from sys import exit source = input("Enter source file with full path: ") target = input("Enter target file with full path: ") # adding exception handling try: copyfile(source, target) except IOError as e: print("Unable to copy file. %s" % e) exit(1) except: print("Unexpected error:", sys.exc_info()) exit(1) print(" File copy done! ") while True: print("Do you like to print the file ? (y/n): ") check = input() if check == 'n': break elif check == 'y': file = open(target, "r") print(" Here follows the file content: ") print(file.read()) file.close() print() break else: Continue
Shutil Copy()方法
copyfile(source_file, [destination_file or dest_dir])
copy() 方法的功能類似于 Unix 中的“cp”命令。這意味著如果目標(biāo)是一個(gè)文件夾,那么它將在其中創(chuàng)建一個(gè)與源文件具有相同名稱(基本名稱)的新文件。此外,該方法會(huì)在復(fù)制源文件的內(nèi)容后同步目標(biāo)文件權(quán)限到源文件。
import os import shutil source = 'current/test/test.py' target = '/prod/new' assert not os.path.isabs(source) target = os.path.join(target, os.path.dirname(source)) # create the folders if not already exists os.makedirs(target) # adding exception handling try: shutil.copy(source, target) except IOError as e: print("Unable to copy file. %s" % e) except: print("Unexpected error:", sys.exc_info())
copy() vs copyfile() :
copy() 還可以在復(fù)制內(nèi)容時(shí)設(shè)置權(quán)限位,而 copyfile() 只復(fù)制數(shù)據(jù)。
如果目標(biāo)是目錄,則 copy() 將復(fù)制文件,而 copyfile() 會(huì)失敗,出現(xiàn) Error 13。
有趣的是,copyfile() 方法在實(shí)現(xiàn)過程中使用 copyfileobj() 方法,而 copy() 方法則是依次使用 copyfile() 和 copymode() 函數(shù)。
在 Potion-3 可以很明顯看出 copyfile() 會(huì)比 copy() 快一點(diǎn),因?yàn)楹笳邥?huì)有一個(gè)附加任務(wù)(保留權(quán)限)。
Shutil Copyfileobj()方法
該方法將文件復(fù)制到目標(biāo)路徑或者文件對(duì)象。如果目標(biāo)是文件對(duì)象,那么你需要在調(diào)用 copyfileobj() 之后關(guān)閉它。它還假定了一個(gè)可選參數(shù)(緩沖區(qū)大小),你可以用來設(shè)置緩沖區(qū)長度。這是復(fù)制過程中保存在內(nèi)存中的字節(jié)數(shù)。系統(tǒng)使用的默認(rèn)大小是 16KB。
from shutil import copyfileobj status = False if isinstance(target, string_types): target = open(target, 'wb') status = True try: copyfileobj(self.stream, target, buffer_size) finally: if status: target.close()
Shutil Copy2()方法
雖然 copy2() 方法的功能類似于 copy()。但是它可以在復(fù)制數(shù)據(jù)時(shí)獲取元數(shù)據(jù)中添加的訪問和修改時(shí)間。復(fù)制相同的文件會(huì)導(dǎo)致 SameFileError 異常。
copy() vs copy2() :
copy() 只能設(shè)置權(quán)限位,而 copy2() 還可以使用時(shí)間戳來更新文件元數(shù)據(jù)。
copy() 在函數(shù)內(nèi)部調(diào)用 copyfile() 和 copymode(), 而 copy2() 是調(diào)用 copystat() 來替換copymode()。
Os Popen()方法
from shutil import * import os import time from os.path import basename def displayFileStats(filename): file_stats = os.stat(basename(filename)) print(' Mode :', file_stats.st_mode) print(' Created :', time.ctime(file_stats.st_ctime)) print(' Accessed:', time.ctime(file_stats.st_atime)) print(' Modified:', time.ctime(file_stats.st_mtime)) os.mkdir('test') print('SOURCE:') displayFileStats(__file__) copy2(__file__, 'testfile') print('TARGET:') displayFileStats(os.path.realpath(os.getcwd() + '/test/testfile'))
該方法創(chuàng)建一個(gè)發(fā)送或者接受命令的管道。它返回一個(gè)打開的并且連接管道的文件對(duì)象。你可以根據(jù)文件打開模式將其用于讀取或者寫入比如‘r’(默認(rèn))或者‘w’。
os.popen(command[, mode[, bufsize]])
mode – 它可以是‘r’(默認(rèn))或者‘w’
Bufsize – 如果它的值是0,那么就不會(huì)出現(xiàn)緩沖。如果將它設(shè)置為1,那么在訪問文件時(shí)就會(huì)發(fā)生行緩沖。如果你提供一個(gè)大于1的值,那么就會(huì)在指定緩沖區(qū)大小的情況下發(fā)生緩沖。但是,對(duì)于負(fù)值,系統(tǒng)將采用默認(rèn)緩沖區(qū)大小。
對(duì)于Windows系統(tǒng):
import os os.popen('copy http://m.xsypw.cn/images/chaijie_default.png 2.txt.py')
對(duì)于Liunx系統(tǒng):
import os os.popen('cp http://m.xsypw.cn/images/chaijie_default.png 2.txt.py')
Os System()方法
這是運(yùn)行任何系統(tǒng)命令的最常用方式。使用 system() 方法,你可以調(diào)用 subshell 中的任何命令。在內(nèi)部,該方法將調(diào)用 C 語言的標(biāo)準(zhǔn)庫函數(shù)。
該方法返回該命令的退出狀態(tài)。
對(duì)于 Windows 系統(tǒng):
import os os.system('copy http://m.xsypw.cn/images/chaijie_default.png 2.txt.py')
對(duì)于 Liunx 系統(tǒng):
import os os.system('cp http://m.xsypw.cn/images/chaijie_default.png 2.txt.py')
使用異步方式的線程庫復(fù)制文件
如果你想以異步方式復(fù)制文件,那么使用下面的方法。在這里,我們使用 Python 的線程模塊在后臺(tái)進(jìn)行復(fù)制操作。
在使用這種方法時(shí),請(qǐng)確保使用鎖定以避免鎖死。如果你的應(yīng)用程序使用多個(gè)線程讀取/寫入文件,就可能會(huì)遇到這種情況。
import shutil from threading import Thread src="http://m.xsypw.cn/images/chaijie_default.png" dst="3.txt.py" Thread(target=shutil.copy, args=[src, dst]).start()
使用Subprocess的Call()方法復(fù)制文件
Subprocess 模塊提供了一個(gè)簡單的接口來處理子進(jìn)程。它讓我們能夠啟動(dòng)子進(jìn)程,連接到子進(jìn)程的輸入/輸出/錯(cuò)誤管道,并檢索返回值。
subprocess 模塊旨在替換舊版模塊和函數(shù),比如 – os.system, os.spawn, os.popen, popen2.*
它使用 call() 方法調(diào)用系統(tǒng)命令來執(zhí)行用戶任務(wù)。
import subprocess src="http://m.xsypw.cn/images/chaijie_default.png" dst="2.txt.py" cmd='copy "%s" "%s"' % (src, dst) status = subprocess.call(cmd, shell=True) if status != 0: if status < 0: print("Killed by signal", status) else: print("Command failed with return code - ", status) else: print('Execution of %s passed! ' % cmd)
使用 subprocess 中的 Check_output() 方法復(fù)制文件
使用 subprocess 中的 Check_output() 方法,你可以運(yùn)行外部命令或程序并捕獲其輸出。它也支持管道。
import os, subprocess src=os.path.realpath(os.getcwd() + "http://cdn.techbeamers.com/http://m.xsypw.cn/images/chaijie_default.png") dst=os.path.realpath(os.getcwd() + "http://cdn.techbeamers.com/2.txt.py") cmd='copy "%s" "%s"' % (src, dst) status = subprocess.check_output(['copy', src, dst], shell=True) print("status: ", status.decode('utf-8'))
-
Linux
+關(guān)注
關(guān)注
87文章
11509瀏覽量
213738 -
文件
+關(guān)注
關(guān)注
1文章
579瀏覽量
25359 -
python
+關(guān)注
關(guān)注
56文章
4827瀏覽量
86707
原文標(biāo)題:用Python復(fù)制文件的9個(gè)方法
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
python學(xué)習(xí)--文件操作
C語言-文件操作
使用Python復(fù)制文件的方法有哪些

使用python實(shí)現(xiàn)文件處理的資料詳細(xì)說明

python文件和目錄的操作方法介紹和實(shí)例說明

python文件和目錄的操作方法介紹和實(shí)例說明

python文件操作是什么

如何使用Python讀取寫入Word文件
Python教你用 Rows 快速操作csv文件
如何用Python來實(shí)現(xiàn)文件系統(tǒng)的操作功能

hyper v 復(fù)制,hyper v 復(fù)制如何操作

評(píng)論