Kopieren individuell

Du hast eine Idee für ein Projekt?
JohnWorks
User
Beiträge: 10
Registriert: Freitag 15. April 2011, 12:20

Und hat nun auch noch jemand eine Idee Verzeichnisse (samt Daten und Unterverzeichnissen) von A nach B kopiere?
Gibt es noch gute Einführende Beispiele zum Modul os und shutil?
HORSEPOWER
IS NOTHING WITHOUT
BRAINPOWER.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

JohnWorks hat geschrieben:Und hat nun auch noch jemand eine Idee Verzeichnisse (samt Daten und Unterverzeichnissen) von A nach B kopiere?
Gibt es noch gute Einführende Beispiele zum Modul os und shutil?
Hast Du Dir die Doku mal genau angeguckt und ein wenig herumprobiert? So schwer sollte das doch nicht sein...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
JohnWorks
User
Beiträge: 10
Registriert: Freitag 15. April 2011, 12:20

Code: Alles auswählen

#!/usr/bin/python

import shutil
import datetime

#Pfandangeben USB, NETZWERKLAUFWERK
USB = r'C:\Python27\Test\Usb'
NETZLAUFWERK = r'C:\Python27\Test\Netzlaufwerk'

#Ermittlung der Zeit fuer Pfadangabe
now = datetime.datetime.now()
d = now.date()
t = now.utcnow()

#Ziel auf USB
DESTINATION = USB + now.strftime("\%y%m%d%H%M%S")

shutil.copytree(NETZLAUFWERK, DESTINATION)

print 'Ende'
So mit ein bisschen einlesen hat das nun auch alles geklappt. Nun habe ich noch eine Frage die ich mir beim einlesen nicht beantworten konnte. Und zwar möchte ich gerne in Prozent wissen wieviel kopiert worden ist (Ziel: Später soll ein GUI dazukommen über die man das ganze bedienen soll! Und dort soll dann ein Balken angezeigt werden wieviel Prozent kopiert sind).

Zweite Sache, wie und wo speichert man am besten die Konfigurationsdaten (in meinem Fall erstmal die Beiden Pfade, später sollen noch andere Einstellungsmöglichkeiten hinzukommen?).
HORSEPOWER
IS NOTHING WITHOUT
BRAINPOWER.
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

JohnWorks hat geschrieben:Und zwar möchte ich gerne in Prozent wissen wieviel kopiert worden ist (Ziel: Später soll ein GUI dazukommen über die man das ganze bedienen soll! Und dort soll dann ein Balken angezeigt werden wieviel Prozent kopiert sind).
Das ist leider nicht so einfach. Dieser Comic illustriert ein bisschen, das auch andere Programmierer damit Schwierigkeiten haben.

Leider ist nur sehr schwer abzuschaetzen, wie lange das Kopieren in der Zukunft aussieht.
Z.B. brauchen kleine Dateien tendentiell laenger als grosse (bezogen auf ihre Groesse).

Du muesstest, um es einigermassen praezise zu gestalten, die Dateigroessen vorher einlesen und mit einer Formel die benoetigte Dauer ausrechnen.
Vermutlich waere das aber dann voellig vom Rechner abhaengig.
Ausserdem wuerde sich dadurch der ganze Prozess verlaengern (Alles Dateien vor dem Kopieren durchgehen dauert auch seine Zeit).
lunar

@Liffi: Der OP hat nicht von Zeit gesprochen. Eine prozentuale Anzeige des Fortschritts kann sich auch beziehen auf die Anzahl der bereits kopierten Bytes im Verhältnis zur Gesamtgröße aller zu kopierenden Dateien. Eine solche Anzeige ist relativ zuverlässig.

@JohnWorks: Du musst eben vorher das zu kopierende Verzeichnis durchlaufen, die Anzahl der Dateien sowie ihre Größe bestimmen, und anschließend nochmals durchgehen, um zu kopieren, wobei Du jetzt den Fortschrittsbalken anzeigen und aktualisieren kannst. "shutil.copytree" lässt sich dann natürlich nicht verwenden.
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

lunar hat geschrieben:@Liffi: Der OP hat nicht von Zeit gesprochen. Eine prozentuale Anzeige des Fortschritts kann sich auch beziehen auf die Anzahl der bereits kopierten Bytes im Verhältnis zur Gesamtgröße aller zu kopierenden Dateien. Eine solche Anzeige ist relativ zuverlässig.
Aber die Anzeige ist doch nur brauchbar, wenn die Dateigroesse relativ homogen ist.
Ansonsten hilft einem die Anzeige '75%' recht wenig, wenn das noch dreimal so lange dauert wie die ersten 75%.

EDIT:: Trotzdem kann es natuerlich sinnvoll sein, so etwas zu tun. Benutzer heute denken ja sofort es ist etwas kaputt, wenn sich nichts bewegt oder dreht.
JohnWorks
User
Beiträge: 10
Registriert: Freitag 15. April 2011, 12:20

Also fassen wir nochmal zusammen?! :

1) Alles Verzeichnisse inkl. Unterverzeichnisse auf Dateien durchsuchen und Größe addieren in bsp SummeDatein?
(Da ist schon die erste Frage, wie durchsuche ich Unterverzeichnisse in n Ebenen?)
2) Dann kopiere ich in einem Zweiten Durchlauf die Verzeichnisse und Datein? (Dateien ist klar, aber wie kopiere ich eine komplette Verzeichnisstruktur?) Zudem addiere ich jede kopierte Dateigröße auf bsp SummeKopie und lasse mir dann die Differenz in Prozent zu SummeDatein anzeigen.

Kann ich das vergleichen in einem eigenen Prozess laufen lassen (-- Subprozess?), der quasi einmal die Sek. ausgeführt wird?
HORSEPOWER
IS NOTHING WITHOUT
BRAINPOWER.
BlackJack

@JohnWorks: Zu 1) `os.walk()`.

Zu 2) Na Du fängst einfach auf der obersten Ebene an und kopierst alle Dateien. Dann legst Du alle Verzeichnisse in der Ebene an und kopierst da dann die Dateien hinein und so weiter. Also Du gehst alle Dateien und Verzeichnisse der Quelle durch. Siehe 1).

Letztendlich kannst Du Dir in Schritt eins die Daten auch alle merken.

Von Unterprozessen (oder Threads) würde ich hier die Finger lassen, das ist unnötige Komplexität. Du müsstest Deine Kopierfunktion einfach nur eine Rückruffunktion übergeben können, mit der man den Fortschritt irgend wo hin melden kann.
JohnWorks
User
Beiträge: 10
Registriert: Freitag 15. April 2011, 12:20

Code: Alles auswählen

#!/usr/bin/python
import os

def iter_files(path):
    files = []

    for root, dirs, filenames in os.walk(path):
        for filename in filenames:
           files.append(os.path.join(root, filename))

    return files

def get_dir_size(directory):
    files = iter_files(directory)
    dir_size = 0

    for file in files:
        dir_size += os.path.getsize(file)
    
    return dir_size


dirname = r'D:\____Test\Test'
print get_dir_size(dirname)
Gibt mir die tatsächliche Dateigröße aus. Nun gibt es ja bei Windows 'Dateigröße' und 'Größe auf Datenträger'. Das hat wohl was mit dem Cluster der Platte zu tun (http://www.fachinformatiker.de/windows- ... aeger.html) Ist diese immer 512, kann ich den auslesen? Wenn ich schonmal die Größe habe, kann ich in meinem Skript auch direkt prüfen ob die kopierenden Dateien ins Zielverzeichnisspassen (kann ich auch freien Speicherplatz auslesen???).
HORSEPOWER
IS NOTHING WITHOUT
BRAINPOWER.
BlackJack

@JohnWorks: Diese Überprüfung würde ich an Deiner Stelle vergessen. Da spielen einfach zu viele Faktoren mit hinein. Es gibt verschiedene Dateisysteme, transparente Kompression, "sparse files", und die Verzeichniseinträge nehmen ja auch noch einmal nicht wirklich vorhersehbaren Speicherplatz auf dem Datenträger ein.
JohnWorks
User
Beiträge: 10
Registriert: Freitag 15. April 2011, 12:20

BlackJack hat geschrieben:@JohnWorks: Diese Überprüfung würde ich an Deiner Stelle vergessen. Da spielen einfach zu viele Faktoren mit hinein. Es gibt verschiedene Dateisysteme, transparente Kompression, "sparse files", und die Verzeichniseinträge nehmen ja auch noch einmal nicht wirklich vorhersehbaren Speicherplatz auf dem Datenträger ein.
OK, vielleicht wäre die "einfache Möglichkeit" die Summe der Daten um 1% zu erhöhen?! Einen Tipp zu den Konfigurationsdaten, wie ich die am besten auslager?!

Code: Alles auswählen

#!/usr/bin/python
import os

def getFreeSpace( Laufwerk ):
    txt = os.popen( 'dir %s\\' % Laufwerk ).readlines()
    txt = txt[-1]
    txt = txt.split(",")[1]
    txt = txt.split("Bytes")[0]
    txt = "".join( txt.split(".") )
    return int( txt )

Bytes = getFreeSpace( "D:" )
print Bytes / 1024 / 1024, "MB frei"
@ Jedoch stimmt die freie Größe nicht mit der vom System angeben Größe überein? Ist das korrekt?
HORSEPOWER
IS NOTHING WITHOUT
BRAINPOWER.
Antworten