Kopieren von Dateien visualisieren ... tqdm?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
drnicolas
User
Beiträge: 105
Registriert: Sonntag 24. Juli 2016, 10:32

Mein Skript kopiert Bilder (jpgs) von Arthroskopien.
Die Bilder (und Videos plus weitere Dateien) landen auf einem USB-Stick. Von diesem kopiert das Skript
Leider sind das viele dateien und es dauert ganz schön lange.

Dieser Prozess soll visualisiert werden - vorzugsweise geht es darum den Fortschritt irgendwie darzustellen.
Leider kommt es vor, dass meine Damen die Geduld verlieren und den Stick ziehen bevor das Kopieren abgeschlossen ist.

Kann ich das mit tqdm lösen? Es müsste nach jeder datei der Fortschrittsbalken hochgezählt werden.
Irgendwie scheinen aber die Beispiele nur Zahlen hochzuzählen.

Oder gibt es was Besseres?
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

Du sammelst die zu kopierenden Dateien ja sicherlicher in irgendeiner Datenstruktur und iterierst über diese, um den Kopierprozess zu starten. Diese Datenstruktur kannst du mit tqdm verwenden. Beispiel ohne Zahlen:

Code: Alles auswählen

from tqdm import tqdm
things = ["foo", "bar", "baz"]
for thing in tqdm(things):
    # Datei kopieren
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Was hast Du versucht?

So etwas ungefähr:

Code: Alles auswählen

import shutil
from pathlib import Path
from tqdm import tqdm

def copy_files_with_progress(source_path: Path, destination_path: Path):
    # Ensure destination path exists
    destination_path.mkdir(parents=True, exist_ok=True)
    
    # Get all files in the source directory
    filenames = list(source_path.glob('*'))
    
    # Copy files with progress
    for filename in tqdm(filenames, desc="Copying files"):
        shutil.copy(filename, destination_path)
Benutzeravatar
DeaD_EyE
User
Beiträge: 1218
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Noch ein Beispiel ohne externe Abhängigkeiten.

Code: Alles auswählen

from shutil import copytree, copystat, copymode
from pathlib import Path


class CopyTreeProgress:
    def __init__(self, src: str | Path, dst : str | Path):
        self.source_directory = Path(src)
        copytree(src, dst, copy_function=self._copy_func, dirs_exist_ok=True)

    def _copy_func(self, src, dst):
        src, dst = map(Path, (src, dst))
        size = src.stat().st_size

        # Überspringe bei gleicher Größe
        if dst.exists() and dst.stat().st_size == size:
            print(f"Gleiche Größe, überspringe {src.relative_to(self.source_directory)}")
            return

        with (
            src.open("rb") as fd_in,
            dst.open("wb") as fd_out,
        ):
            buffer = bytearray(64 * 1024 ** 1)
            view = memoryview(buffer)

            done = 0

            while chunk_size := fd_in.readinto(buffer):
                fd_out.write(view[:chunk_size])
                done += chunk_size
                self.show_progress(src.relative_to(self.source_directory), done / size)

            copystat(src, dst)
            copymode(src, dst)
            print()
    
    @staticmethod
    def show_progress(file: str | Path, relative: float):
        size = 20
        bar = "#" * round(relative * size) + " " * round((1 - relative) * size)
        print(f"\r{bar} {relative:>6.1%} {file}", end="", flush=True)


downloads = Path.home().joinpath("Downloads")
downloads2 = Path.home().joinpath("Downloads2")
progress = CopyTreeProgress(downloads, downloads2)
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten