Einführung
Wenn Sie Python zum Kopieren von Dateien verwenden möchten, gibt es zwei Möglichkeiten: Verwenden Sie das Modul shutil
oder das Modul os
. Alle os
-Methoden, die wir hier zeigen, sind Methoden, mit denen wir Shell-Befehle aus unserem Python-Code ausführen können, mit denen wir den copy
-Befehl (Windows) oder den cp
-Befehl (Unix) ausführen.
Sie werden feststellen, dass viele dieser Methoden sowohl im shutil
Modul als auch im os
Modul sehr ähnliche Funktionen haben (was nicht überraschend sein sollte), aber jede unterscheidet sich in der Funktionalität sehr geringfügig voneinander, was ich auch erklären werde.
Kopieren von Dateien mit dem Shutil-Modul
Das shutil-Modul bietet mehrere übergeordnete Methoden zum Kopieren von Dateien. Hier sind die wichtigsten:
copyfile
Diese Methode kopiert den Inhalt einer Datei in eine andere Datei. Das angegebene Ziel muss eine beschreibbare Datei sein und einen anderen Namen als die Quelldatei haben. Wenn die Namen gleich sind, wird ein Fehler generiert. Wenn die Zieldatei bereits vorhanden ist, wird sie durch die neu kopierte Datei ersetzt.
Die Syntax für diese Methode lautet:
shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)
Der folgende Code kopiert beispielsweise eine Datei mit dem Namen „file1.txt“ in eine Datei mit dem Namen „file2.txt“:
import shutilshutil.copyfile('file1.txt', 'file2.txt')
Ein interessantes und potentiell nützliches Feature von shutil.copyfile
ist das follow_symlinks
Boolesche Argument. Wenn es auf False
gesetzt ist und die Quelldatei ein symbolischer Link ist, wird anstelle des Kopierens der Datei ein neuer symbolischer Link erstellt.
kopieren
Diese Methode ist copyfile
sehr ähnlich, mit dem Hauptunterschied, dass zusätzlich zum Kopieren des Inhalts der Quelldatei noch ein Schritt weiter geht und auch die Dateisystemberechtigungen der Datei kopiert werden. Das Kopieren von Dateiberechtigungen ist in den meisten Programmiersprachen keine triviale Aufgabe.
Die Syntax lautet wie folgt:
shutil.copy(src_file, dest_file, *, follow_symlinks=True)
Jeder dieser Parameter ist der gleiche wie in der copyfile
Methode. Der folgende Code kopiert beispielsweise „Datei1.txt“ in „Datei3.txt“.
import shutilshutil.copy('file1.txt', 'file3.txt')
Hinweis: Stellen Sie sicher, dass Sie Ihr Skript nicht genauso benennen wie eines der Module, die Sie importieren (was ich fälschlicherweise beim Testen von Code für diesen Artikel getan habe). Wenn Sie dies tun, wird beim Versuch, dieses Modul zu importieren, aufgrund eines zirkulären Importproblems eine Fehlermeldung angezeigt.
copy2
Wie bei den vorherigen Methoden ist die copy2
Methode identisch mit der copy
Methode, aber zusätzlich zum Kopieren des Dateiinhalts wird auch versucht, alle Metadaten der Quelldatei beizubehalten. Wenn die Plattform das vollständige Speichern von Metadaten nicht zulässt, gibt copy2
keinen Fehler zurück und behält nur alle Metadaten bei, die es kann.
Die Syntax ist wie folgt:
shutil.copy2(src_file, dest_file, *, follow_symlinks=True)
Auch hier sind diese Parameter die gleichen wie in den vorherigen Befehlen, die wir bisher erwähnt haben.
Der folgende Code kopiert beispielsweise „Datei1.txt“ in „Datei4.txt“, sowie bewahren Sie die Metadaten der Originaldatei, „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
Wie wir aus der Ausführung unseres obigen Codes sehen können, „file1.txt“ wurde in „file4″ kopiert.txt“. Möglicherweise haben Sie jedoch bemerkt, dass das Erstellungsdatum in der neuen Datei beibehalten wurde, im Gegensatz zu shutil.copy
, das „file1 .txt“ zu „Datei3.txt“ und gab ihm ein neues Erstellungsdatum.
copyfileobj
Diese Methode kopiert den Inhalt einer Quelldatei von der aktuellen Position der Quelldatei in eine Zieldatei. Dies bedeutet, dass, wenn Sie Daten aus Ihrem Quelldateiobjekt lesen, die Position, an der Sie aufhören zu lesen, die Position ist, von der aus copyfileobj
kopiert wird.
Die Syntax lautet wie folgt:
shutil.copyfileobj(src_file_object, dest_file_object)
Die Bedeutung von Quell- und Zieldateiparametern ähnelt den vorherigen Befehlen, bezieht sich jedoch auf Objekte. Der Parameter length ist optional und stellt die Puffergröße dar, d. h. die Anzahl der Bites, die während des Kopiervorgangs im Speicher gespeichert werden. Diese Option kann beim Kopieren sehr großer Dateien nützlich sein, da sie den Kopiervorgang beschleunigen und eine unkontrollierte Speichernutzung vermeiden kann.
Zum Beispiel kopiert der folgende Code „file1.txt“ in „Datei5.txt“
import shutilfilename1 = 'file1.txt'fileA = open(filename1, 'rb')filename2 = 'file5.txt'fileB = open(filename2, 'wb')shutil.copyfileobj(fileA, fileB)
Wie wir sehen können, müssen wir die Dateien im Binärmodus öffnen, um copyfileobj
zu verwenden (das ist der „b“ -Teil von „rb“ und „wb“). Darüber hinaus muss die Quelldatei als lesbar und die Zieldatei als beschreibbar geöffnet werden (die Teile „r“ bzw.
Kopieren von Dateien mit dem Betriebssystemmodul
Das Betriebssystemmodul bietet eine Möglichkeit, die Betriebssystemfunktionen zum Kopieren Ihrer Dateien zu verwenden. In den meisten (wenn nicht allen) Beispielen von hier aus stellen wir Beispiele zur Verfügung, die sowohl für Windows als auch für Unix funktionieren. Achten Sie daher darauf, wie jeder Funktionsaufruf in den Python-Kommentaren gekennzeichnet ist.
popen
Diese Methode öffnet eine Pipe zu oder von Ihrem Befehl. Beachten Sie jedoch, dass diese Methode in Python 2.6 veraltet ist. Alternativ empfiehlt uns die Python-Dokumentation, stattdessen Methoden aus dem Unterprozessmodul zu verwenden.
Die Syntax lautet wie folgt:
os.popen(cmd])
Hier ist der zurückgegebene Wert ein Dateiobjekt, das mit der Pipe verbunden ist. Dieses Objekt kann je nach Modus gelesen oder geschrieben werden. Der Standardmodus ist ‚r‘, der das Lesen des Dateiinhalts ermöglicht.
Das folgende Beispiel kopiert „Datei1.txt“ in „Datei6.txt“:
import os# Windowsos.popen('copy file1.txt file6.txt')# Unixos.popen('cp file1.txt file6.txt')
Das Ausführen des Befehls auf diese Weise ist genau dasselbe, als ob Sie ihn direkt über die Befehlszeile Ihres Terminals ausführen würden.
system
Diese Methode führt den angegebenen Befehl in einer Subshell aus. Es ist sowohl für Unix als auch für Windows verfügbar. Die Syntax lautet wie folgt:
os.system(command)
Hier command
ist eine Zeichenfolge, die den DOS- oder Unix-Shell-Befehl enthält. In unserem Fall setzen wir hier den Befehl copy
oder cp
.
Der folgende Code kopiert beispielsweise „Datei1.txt“ in „Datei7.txt“
import os# Windowsos.system('copy file1.txt file7.txt')# Unixos.system('cp file1.txt file7.txt')
Dies sieht identisch aus mit dem vorherigen os.popen
Befehl, den wir gerade verwendet haben, aber der Befehl wird in einer Subshell ausgeführt, was bedeutet, dass er parallel zu Ihrem ausführenden Code in einem separaten Thread ausgeführt wird. Um auf den Abschluss zu warten, müssen Sie .wait()
für das von os.system
zurückgegebene Objekt aufrufen.
Kopieren von Dateien mit dem Unterprozessmodul
Das Unterprozessmodul beabsichtigt, einige Methoden im os
-Modul (insbesondere os.system
und die os.spawn*
-Methoden) zu ersetzen, und stellt zwei Hauptmethoden für den Zugriff auf die Betriebssystembefehle vor. Diese Methoden sind call
und check_output
. Noch einmal, für Unix-Systeme, der Befehl „copy file1.txt-Datei2.txt“ sollte durch „cp file1″ ersetzt werden.txt-Datei2.txt“.
Methode aufrufen
Die Python-Dokumentation empfiehlt uns, die call
Methode zu verwenden, um einen Befehl vom Betriebssystem aus zu starten.
Die Syntax lautet wie folgt:
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
Der Parameter args
enthält unseren Shell-Befehl. Ein Wort der Vorsicht, da die Python-Dokumentation uns warnt, dass die Verwendung von shell=True
ein Sicherheitsrisiko darstellen kann.
Mit diesem Funktionsaufruf können wir unseren copy-Befehl wie folgt ausführen:
import subprocess# Windowsstatus = subprocess.call('copy file1.txt file8.txt', shell=True)# Unixstatus = subprocess.call('cp file1.txt file8.txt', shell=True)
Wie das obige Beispiel zeigt, müssen wir einfach wie zuvor eine Zeichenfolge mit dem Shell-Befehl übergeben.
Und wie erwartet kopiert das Betriebssystem „file1.txt“ in eine Datei mit dem Namen „file8.txt“.
check_output-Methode
Mit dieser Methode können wir auch einen Befehl innerhalb einer Shell ausführen. Es ist dem Befehl subprocess.run
sehr ähnlich, außer dass er standardmäßig Daten von stdout als codierte Bytes weiterleitet. Die Syntax lautet wie folgt:
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)
Hier enthält der Parameter args
den Shell-Befehl, den wir verwenden möchten. Die Python-Dokumentation warnt uns erneut vor der Verwendung von shell=True
.
Im folgenden Code kopieren wir „file1.txt“ zu „Datei9.txt“ mit dem check_output
Befehl:
import subprocess# Windowsstatus = subprocess.check_output('copy file1.txt file9.txt', shell=True)# Unixstatus = subprocess.check_output('cp file1.txt file9.txt', shell=True)
Und wie bei allen Befehlen, die wir in diesem Artikel gezeigt haben, wird dadurch die Datei „file1.txt“ an das von uns angegebene Ziel „file9.txt“ hier.
Einwickeln
Python bietet uns viele verschiedene Möglichkeiten, Dateien zu kopieren, von denen einige Teil des Python-Methodensatzes sind. Andere verwenden einige der leistungsfähigen Methoden von Python, um Befehle in einer Shell auszuführen, die Shell-Befehle wie copy
oder cp
.
Nicht sicher, welches für Sie das richtige ist? Wir haben hier viele verschiedene Möglichkeiten zum Kopieren von Dateien vorgestellt, das ist also verständlich. Die Methode, mit der Sie eine Datei kopieren, liegt ganz bei Ihnen und hängt von Ihren spezifischen Anforderungen ab. Obwohl in den meisten Fällen einer der shutil
Befehle für Sie einwandfrei funktioniert. Versuchen Sie, mit shutil.copy2
und sehen Sie, ob das das tut, was Sie brauchen.