Seite 1 von 1
Kopieren von vielen einzelnen Dateien
Verfasst: Freitag 7. Februar 2020, 16:14
von Tim533
Hallo zusammen,
das folgende Problem bereitet mir seit Wochen Kopfzerbrechen:
Ich habe 2,7 mio. Bilddaten für die Erstellung einer künstlichen Intelligenz auf einer externen Festplatte (4Tb SSD) gesichert. Die Bilder sind zwischen 300 kb und 1,7 mb groß und befinden sich alle in einem Ordner. Um diese Daten vernünftig für die KI zu verarbeiten, müssen diese erstmal sortiert werden. Das Python-Skript hierfür ist bereits geschrieben, getestet und funktioniert wunderbar. Das ganze soll aber auf meiner lokalen Festplatte (NVMe Standard | M.2 | Samsung 970 EVO Plus | 2TB) gemacht werden da ich es auf der SSD bereits probiert habe und es ewig dauern würde. Also das Bottleneck ist auf jeden Fall die externe Festplatte.
Wie bekomme ich die einzelnen Dateien auf meine lokale Festplatte kopiert? Am liebsten würde ich es Stück für Stück machen. Also zB immer 100.000 Bilder. Hat jemand eine Idee wie ich das ganze mit Python machen könnte? Ihr seid meine letzte Hoffnung.
Viele Dank und viele Grüße, Tim
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Freitag 7. Februar 2020, 16:17
von __deets__
Du versuchst gerade rsync neu zu erfinden. Benutz einfach das.
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Freitag 7. Februar 2020, 18:40
von nezzcarth
Rsync ist sicher eine gute und einfache Methode, um das noch etwas effizienter zu gestalten. Nur sollte man sich auch klar machen, dass es Grenzen gibt, wie weit man das optimieren kann. Ab einer bestimmten Größe dauert es halt und da gibt es dann nicht mehr so viel, was man noch tun kann, außer sich in Geduld zu üben.
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Freitag 7. Februar 2020, 22:28
von __blackjack__
Ich würde rsync nicht mal unter dem Gesichtspunkt der Geschwindigkeit beim kopieren sehen, sondern dass das schon *fertig verfügbar* ist, statt das man da noch selbst etwas programmieren müsste. Wo man Fehler machen kann. Das es vielleicht marginal geringfügig schneller kopiert als eine Kopierschleife die in Python geschrieben ist, wäre für mich da nicht so entscheidend.
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Freitag 7. Februar 2020, 22:49
von nezzcarth
__blackjack__ hat geschrieben: Freitag 7. Februar 2020, 22:28
Ich würde rsync nicht mal unter dem Gesichtspunkt der Geschwindigkeit beim kopieren sehen, sondern dass das schon *fertig verfügbar* ist, statt das man da noch selbst etwas programmieren müsste.
Wenn die Begründung wirklich ausschließlich ist, dass man es nicht selbst programmieren muss, verstehe ich nicht, weshalb die Empfehlung rsync und nicht und nicht einfach so etwas wie 'cp -Rua' (oder ein hoffentlich existentes Windows-Gegenstück) ist.
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Freitag 7. Februar 2020, 23:09
von __blackjack__
@nezzcarth: Gerade bei solchen Datenmengen würde ich ungern etwas nehmen wollen was man nicht abbrechen kann und dann ohne noch mal komplett von vorne anfangen zu müssen wieder anstossen kann.
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Freitag 7. Februar 2020, 23:11
von nezzcarth
Ja, das verstehe ich, und mache das ja auch so. Nur ist dann aber eben doch eine andere Begründung...

(Sorry für die Erbenzählerei... :/ Aber es sollte halt schon durchkommen, warum rsync hier die richtige Wahl ist, finde ich )
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Samstag 8. Februar 2020, 00:21
von __deets__
Es ist richtige Wahl weil es wie alles was der TE programmieren wollen würde nur kopiert was nicht schon kopiert wurde. Dein cp tut das nicht.
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Samstag 8. Februar 2020, 16:46
von thomas38
Hallo Tim,
von mir mal etwas Konkretes:
Voraussetzungen/Annahmen:
- Es sollen ca. 2,7 Mio Dateien von einer externen SSD-Festplatte vermutlich über USB2 oder USB3 (hoffentlich) angeschlossen auf die lokale SSD-Festplatte kopiert werden.
- Das Betriebssystem ist Windows10 oder Linux
- Der Kopiervorgang soll entweder nach einer bestimmten Anzahl zu kopierende Dateien oder durch ein anderes externen Ereignis beendet werden und beim erneuten Start nur fortgesetzt werden: bereits kopierte Dateien sollen nicht erneut kopiert werden.
- Auf der internen Festplatte ist noch genügend Platz für die Dateien vorhanden
Lösungsansätze:
Lösung A: Kopieren mit "Bordmitteln" des verwendeten Betriebssystems (Mit entsprechenden Optionen werden bereits bestehende Dateien nicht erneut kopiert):
Windows10: robocopy (ist bereits nach einer Installation vorhanden)
Linux: rsync (ist bereits nach einer Installation vorhanden oder kann einfach nachinstalliert werden)
Vorteil: Kein weiteres Programm erforderlich
Nachteil: Diese Programme müssen manuell abgebrochen werden, wenn der Kopiervorgang "unterbrochen" werden soll.
Lösung B: Python Programm:
Vorteil: Kontrollierter Abbruch: Es werden pro Aufruf nur eine bestimmte Anzahl von Dateien kopiert oder es wird durch ein externes Ereignis ordentlich beendet
Nachteil: Es muss geschrieben werden
Ablauf des Programms:
Code: Alles auswählen
Wenn Stop-Datei vorhanden ist:
Stop-Datei löschen
# Die Existenz der Stop-Datei ist das externe Ereignis, welches das Kopierprogramm signalisiert, ordentlich zu beenden.
# Zu Beginn des Programms wird diese Datei ggf gelöscht, da das Programm sonst gar nichts macht
Wenn Datei "copied_files.txt" mit bereits kopierten Dateinamen vorhanden ist:
Datei "copied_files.txt" lesen und in dict "copied_files" speichern
Datei "copied_files.txt" schreibend zum Anhängen öffnen
# Dort werden die in diesem Aufruf erfolgreich kopierten Dateinamen angehängt
Über alle Dateien im Quellverzeichnis:
Wenn die maximale Anzahl von zu kopierenden Dateien erreicht ist:
Programmende
Wenn Stop-Datei existiert:
Programmende
Wenn Dateiname nicht in dict "copied_files" vorhanden ist:
kopiere Datei ins Zielverzeichnis
# z.B. mit shutil.filecopy
Wenn Kopiervorgang erfolgreich:
Dateinamen dem dict "copied_files" hinzufügen
Dateinamen an "copied_files.txt" anhängen
Anzahl der kopierten Dateien um 1 erhöhen
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Samstag 8. Februar 2020, 18:52
von __blackjack__
@thomas38: Was enthält denn das Wörterbuch `copied_files`? Sicher dass das ein `dict` und kein `set` sein sollte‽ Die Textdatei wäre mir ja auch nicht robust genug. Dateinamen können schliesslich Zeilenendezeichen enthalten — wie geht man damit in einer Textdatei um? Das müsste also mindestens mal so etwas wie eine CSV-Datei sein, damit Zeilenenden in Namen vom Ende eines Namens unterschieden werden kann.
Weiteres Problem ist die Kodierung. Textdateien haben ja in der Regel *eine* Kodierung. Dateienamen unter Linux/Unix sind aber keine Zeichenketten, sondern Byteketten, das kann also Probleme geben die in einer Textdatei zu speichern.
Warum braucht man diese Datei/das Wörterbuch überhaupt? Man kann doch einfach testen ob die Zieldatei schon existiert und gleich gross ist.
Re: Kopieren von vielen einzelnen Dateien
Verfasst: Samstag 8. Februar 2020, 19:42
von snafu
thomas38 hat geschrieben: Samstag 8. Februar 2020, 16:46
Lösung A: Kopieren mit "Bordmitteln" des verwendeten Betriebssystems (Mit entsprechenden Optionen werden bereits bestehende Dateien nicht erneut kopiert):
Windows10: robocopy (ist bereits nach einer Installation vorhanden)
Linux: rsync (ist bereits nach einer Installation vorhanden oder kann einfach nachinstalliert werden)
Vorteil: Kein weiteres Programm erforderlich
Nachteil: Diese Programme müssen manuell abgebrochen werden, wenn der Kopiervorgang "unterbrochen" werden soll.
Zum Nachteil: Stimmt, aber diese Tools merken ja beim erneuten Programmlauf, was bereits kopiert wurde bzw was aktuell ist. Und die manuelle Unterbrechung kriegst du innerhalb von Python auch hin, wenn du das Kommando über die Popen()-Schnittstelle (im subprocess-Modul) ausführst. Darauf kannst du bei späterem Bedarf die terminate()-Methode aufrufen, um das externe Programm zu beenden. Dies lässt sich natürlich auch mit einem entsprechenden Button innerhalb einer GUI verbinden, falls so etwas geplant ist.