Inleiding
als het gaat om het gebruik van Python om bestanden te kopiëren, zijn er twee manieren: het gebruik van de shutil
module of de os
module. Alle os
methoden die we hier laten zien zijn methoden die ons toelaten om shell commando ‘ s uit te voeren vanuit onze Python code, die we zullen gebruiken om het copy
Commando (Windows) of het cp
Commando (Unix) uit te voeren.
u zult merken dat veel van deze methoden, in zowel de shutil
module en de os
module, zeer vergelijkbare functionaliteit hebben (wat niet verrassend zou moeten zijn), maar elk varieert in functionaliteit van elkaar zeer licht, wat ik ook zal uitleggen.
bestanden kopiëren met de shutil-Module
De shutil-module biedt verschillende methoden op hoog niveau om bestanden te kopiëren. Hieronder zijn de belangrijkste:
copyfile
Deze methode kopieert de inhoud van een bestand naar een ander bestand. De bestemming moet een beschrijfbaar bestand zijn en een andere naam hebben dan het bronbestand. Als de namen hetzelfde zijn dan zal het een fout genereren. Als het doelbestand al bestaat, wordt het vervangen door het nieuw gekopieerde bestand.
de syntaxis voor deze methode is:
shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)
bijvoorbeeld, de volgende code zal een bestand met de naam ” file1 kopiëren.txt ” in een bestand met de naam “file2.txt”:
import shutilshutil.copyfile('file1.txt', 'file2.txt')
een interessante en potentieel nuttige functie van shutil.copyfile
is het follow_symlinks
Booleaans argument. Als het is ingesteld op False
, en het bronbestand een symbolische link is, dan zal in plaats van het bestand te kopiëren een nieuwe symbolische link worden gemaakt.
copy
deze methode is zeer vergelijkbaar met copyfile
, met het belangrijkste verschil is dat naast het kopiëren van de inhoud van het bronbestand, het een stap verder gaat en ook de bestandssysteem permissies van het bestand kopieert. Het kopiëren van bestandsrechten is geen triviale taak in de meeste programmeertalen, dus dit is een leuke functie om te hebben.
de syntaxis is als volgt:
shutil.copy(src_file, dest_file, *, follow_symlinks=True)
elk van deze parameters is hetzelfde als in de copyfile
methode. Bijvoorbeeld, de volgende code zal kopiëren ” file1.txt “in” bestand3.txt”.
import shutilshutil.copy('file1.txt', 'file3.txt')
Opmerking: Zorg ervoor dat u uw script niet dezelfde naam geeft als een van de module die u importeert (wat ik per ongeluk deed bij het testen van code voor dit artikel). Als je dat doet, dan krijg je een fout bij het proberen om die module te importeren als gevolg van een circulaire import probleem.
copy2
net als bij de vorige methoden is copy2
methode identiek aan de copy
methode, maar naast het kopiëren van de inhoud van het bestand probeert het ook alle metagegevens van het bronbestand te behouden. Als het platform het opslaan van volledige metadata niet toestaat, dan geeft copy2
geen fout terug en zal het alleen metadata behouden die het kan.
de syntaxis is als volgt:
shutil.copy2(src_file, dest_file, *, follow_symlinks=True)
nogmaals, deze parameters zijn hetzelfde als in de vorige commando ‘ s die we tot nu toe hebben genoemd.
bijvoorbeeld, de volgende code zal “file1 kopiëren.txt “in” bestand4.txt”, evenals het behoud van de metadata van het oorspronkelijke bestand, “file1.txt”.
import shutilshutil.copy2('file1.txt', 'file4.txt')
$ python copy-files.py $ ls -ltotal 32-rw-r--r-- 1 scott staff 91 Oct 27 11:26 copy-files.py-rw-r--r-- 1 scott staff 6 Oct 27 11:27 file1.txt-rw-r--r-- 1 scott staff 6 Oct 27 11:29 file3.txt-rw-r--r-- 1 scott staff 6 Oct 27 11:27 file4.txt
zoals we kunnen zien bij het uitvoeren van onze code hierboven, ” file1.txt “werd gekopieerd naar” bestand4.txt”. Het is u echter misschien opgevallen dat de aanmaakdatum bewaard is gebleven in het nieuwe bestand, in tegenstelling tot shutil.copy
, die “file1 heeft gekopieerd.TXT “naar” bestand3.txt ” en gaf het een nieuwe aanmaakdatum.
copyfileobj
deze methode kopieert de inhoud van een bronbestand naar een doelbestand, vanuit de huidige bronbestandpositie. Wat dit betekent is dat als je data leest van je bronbestand object, dan is de positie waar je stopt met lezen de positie copyfileobj
vanaf kopieert.
de syntaxis is als volgt:
shutil.copyfileobj(src_file_object, dest_file_object)
De betekenissen van bron-en doelbestandsparameters zijn vergelijkbaar met de vorige commando ‘ s, maar nu verwijzen ze naar objecten. De lengte parameter is optioneel en vertegenwoordigt de buffergrootte dat is het aantal beten in het geheugen gehouden tijdens het kopieerproces. Deze optie kan handig zijn bij het kopiëren van zeer grote bestanden, omdat het het kopieerproces kan versnellen en ongecontroleerd geheugengebruik voorkomt.
bijvoorbeeld de volgende code zal “file1 kopiëren.txt “in” bestand5.txt “
import shutilfilename1 = 'file1.txt'fileA = open(filename1, 'rb')filename2 = 'file5.txt'fileB = open(filename2, 'wb')shutil.copyfileobj(fileA, fileB)
zoals we kunnen zien, om copyfileobj
te gebruiken, moeten we de bestanden openen in binaire modus (dat is het” b “deel van” rb “en”wb”). Daarnaast moet het bronbestand als leesbaar worden geopend en moet het doelbestand als beschrijfbaar worden geopend (respectievelijk de “r” en “w” delen).
bestanden kopiëren met de os-Module
De os-module biedt een manier om de functionaliteit van het besturingssysteem te gebruiken om uw bestanden te kopiëren. In de meeste (zo niet alle) voorbeelden geven we voorbeelden die werken voor zowel Windows als Unix. De voorbeelden zijn verschillend vanwege de shell commando ‘ s die worden gebruikt, dus zorg ervoor dat je aandacht besteedt aan hoe elke functie aanroep wordt gelabeld in de Python comments.
popen
Deze methode opent een pipe naar of van uw commando. Echter, merk op dat deze methode is verouderd in Python 2.6, dus we raden niet aan om het te gebruiken, tenzij je moet. Als alternatief adviseert de Python documentatie ons om in plaats daarvan methoden uit de subprocess module te gebruiken.
de syntaxis is als volgt:
os.popen(cmd])
Hier is de waarde die wordt geretourneerd een bestandsobject dat is verbonden met de pipe. Dit object kan worden gelezen van of geschreven naar afhankelijk van de modus. De standaardmodus is ‘r’, waarmee de inhoud van het bestand kan worden gelezen.
het voorbeeld hieronder zal “file1 kopiëren.txt “in” bestand6.txt”:
import os# Windowsos.popen('copy file1.txt file6.txt')# Unixos.popen('cp file1.txt file6.txt')
het uitvoeren van het commando op deze manier is precies hetzelfde als wanneer u het direct vanaf de commandoregel van uw terminal hebt uitgevoerd.
systeem
Deze methode voert het opgegeven commando uit in een subschell. Het is beschikbaar voor zowel Unix als Windows. De syntaxis is als volgt:
os.system(command)
hier command
is een string die het DOS of Unix shell commando bevat. In ons geval zullen we hier het copy
of cp
Commando plaatsen.
bijvoorbeeld, de volgende code zal “file1 kopiëren.txt “in” bestand7.txt “
import os# Windowsos.system('copy file1.txt file7.txt')# Unixos.system('cp file1.txt file7.txt')
Dit ziet er identiek uit aan het vorige os.popen
commando dat we zojuist hebben gebruikt, maar het commando wordt uitgevoerd in een subshell, wat betekent dat het wordt uitgevoerd in een aparte thread parallel aan uw uitvoerende code. Om te wachten tot het voltooid is, moet u .wait()
aanroepen op het object dat wordt geretourneerd door os.system
.
bestanden kopiëren met de subprocesmodule
De subprocesmodule is bedoeld om enkele methoden in de os
module te vervangen (met name os.system
en de os.spawn*
methoden), en het presenteert twee belangrijke methoden om toegang te krijgen tot de commando ‘ s van het besturingssysteem. Deze methoden zijn call
en check_output
. Nogmaals, Voor Unix systemen, het commando ” kopieer bestand1.txt-bestand2.txt “moet worden vervangen door” CP file1.txt-bestand2.txt”.
aanroepmethode
De Python documentatie raadt ons aan om de call
methode te gebruiken om een commando vanuit het besturingssysteem te starten.
de syntaxis is als volgt:
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
De args
parameter zal ons shell commando bevatten. Echter, een woord van voorzichtigheid, aangezien de Python documentatie ons waarschuwt dat het gebruik van shell=True
een veiligheidsrisico kan zijn.
met behulp van deze functie aanroep, kunnen we ons copy commando als volgt uitvoeren:
import subprocess# Windowsstatus = subprocess.call('copy file1.txt file8.txt', shell=True)# Unixstatus = subprocess.call('cp file1.txt file8.txt', shell=True)
zoals het voorbeeld hierboven laat zien, moeten we gewoon een string doorgeven met het shell commando, zoals eerder.
en zoals verwacht, zal het besturingssysteem “file1 kopiëren.txt ” in een bestand met de naam “file8.txt”.
check_output Method
Deze methode staat ons ook toe om een commando uit te voeren binnen een shell. Het lijkt erg op het subprocess.run
Commando, behalve dat het standaard data van stdout doorgeeft als gecodeerde bytes. De syntaxis is als volgt:
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)
Hier bevat de parameter args
Het shell-commando dat we willen gebruiken. Nogmaals, de Python documentatie waarschuwt ons voor het gebruik van shell=True
, dus gebruik deze methode met voorzichtigheid.
in de volgende code kopiëren we ” file1.TXT “naar” bestand9.txt “using the check_output
command:
import subprocess# Windowsstatus = subprocess.check_output('copy file1.txt file9.txt', shell=True)# Unixstatus = subprocess.check_output('cp file1.txt file9.txt', shell=True)
en zoals met alle commando ’s die we in dit artikel hebben getoond, zal dit het bestand” file1 kopiëren.txt “naar de bestemming die we hebben opgegeven, dat is” file9.txt ” hier.
het afbreken van
Python biedt ons veel verschillende manieren om bestanden te kopiëren, waarvan sommige deel uitmaken van de Python-set van methoden. Anderen gebruiken Enkele van Python ’s krachtige methoden om commando’ s uit te voeren in een shell, die shell commando ‘ s gebruiken zoals copy
of cp
.
weet u niet zeker welke geschikt is voor u? We presenteerden een heleboel verschillende manieren om bestanden te kopiëren hier, dus dat is begrijpelijk. De methode die u gebruikt om een bestand te kopiëren is volledig aan u en zal afhangen van uw specifieke behoeften. Hoewel in de meeste gevallen een van de shutil
commando ‘ s prima zal werken voor u. Probeer te beginnen met shutil.copy2
en kijk of dat doet wat je nodig hebt.