![]() |
Dateien kopieren wird langsam.
Hallo
Ich schreib zur zeit ein programm was viele datein kopieren sol... es funzt auch schon recht gut, jedoch wird es nach ner weile recht langsam. in der funktion "lesedatum" hatte ich zunächst FreeandNil(ImgData) vergessen, wodurch sich der genutzte RAM aufgebläht hat. Doch auch dadurch läuft das prog nicht mit konstanter geschwindigkeit. hat jmd ne ahnung warum es gegen ende immer langsamer wird? hier der code
Delphi-Quellcode:
function LeseDatum(datei:string):string;
var ImgData: TImgData; begin ImgData := TImgData.Create; DexifDecode := true; ImgData.TraceLevel := 1; if ImgData.ProcessFile(datei) then if ImgData.HasExif then LeseDatum := ImgData.ExifObj.DateTime else lesedatum := '' else lesedatum :=''; FreeAndNil(ImgData); end; function TForm1.trennedatum(datum:string) : TStrArray; begin trennedatum[0] := Copy(datum, 1, 4); trennedatum[1] := Copy(datum, 6, 2); trennedatum[2] := Copy(datum, 9, 2); trennedatum[3] := Copy(datum, 12, 2); trennedatum[4] := Copy(datum, 15, 2); trennedatum[5] := Copy(datum, 18, 2); end; procedure TForm1.kopierebilder; var i : integer; jahr,mon,tag : string; n_jahr,n_mon,n_tag : string; fileSource, fileDest: string; begin Progressbar1.Max:=Liste.Count-1; ListBox1.Clear; for i:=0 to Liste.Count-1 do begin Label1.Caption := inttostr(Liste.Count) + ' / ' + inttostr(Liste.Count) + ' Bilder kopiert.'; ListBox1.Items.Add(Liste[i]); Progressbar1.Position :=i; if LeseDatum(Liste[i]) <> '' then begin jahr := trennedatum(LeseDatum(Liste[i]))[0]; mon := trennedatum(LeseDatum(Liste[i]))[1]; tag := trennedatum(LeseDatum(Liste[i]))[2]; n_jahr := Ziel + '\' + jahr; n_mon := Ziel + '\' + jahr + '\' + jahr + '_' + mon; n_tag := Ziel + '\' + jahr + '\' + jahr + '_' + mon + '\' + jahr + '_' + mon + '_' + tag + '-'; {$IOChecks off} if not(DirectoryExists(n_jahr)) then mkdir(n_jahr); if not(DirectoryExists(n_mon)) then mkdir(n_mon); if not(DirectoryExists(n_tag)) then mkdir(n_tag); {$IOChecks on} fileSource := Liste[i]; fileDest := n_tag + '\' + ExtractFileName(Liste[i]); end else begin if not(DirectoryExists(Ziel + '\zeitlos')) then mkdir(Ziel + '\zeitlos'); fileSource := Liste[i]; filedest := Ziel + '\zeitlos' + '\' + ExtractFileName(Liste[i]); end; //ListBox1.Items.Add(filesource); //ListBox1.Items.Add(filedest); CopyFile(PChar(fileSource), PChar(fileDest), true); SendMessage(ListBox1.Handle, LB_SETTOPINDEX, ListBox1.Items.Count-1, 0); end; Progressbar1.Position :=0; end; |
AW: Dateien kopieren wird langsam.
Dateien werden erst in die schnelle WindowsFileCache geschrieben und landen danach erst auf der Festplatte.
Wenn man nun viele/große Dateien in diese WFC reinläd und Windows nicht schnellgenug diese auf die Fesplatte abspeichern kann, dann ist die WFC irgendwann voll und man kann nicht mehr mit voller Geschwindigkeit Neues dort reinladen, da ja erstmal was Altes raus muß. OK, Speicherlecks verbrauchen auch Speicher und verringern somit ebenfalls die Größe/Effektivität der WFC. Und je voller Listen sind, um so länger dauert es, wenn man darin was sucht oder verändert, vorallem sowas wie eine TListBox wird extrem langsam, je mehr darin steht. |
AW: Dateien kopieren wird langsam.
Ich greife hier mal folg. Abschnitt raus:
Delphi-Quellcode:
Das ist eine grosse Verschwendung, denn die Funktion LeseDatum() wird gleich 4 Mal aufgerufen!!
if LeseDatum(Liste[i]) <> '' then
begin jahr := trennedatum(LeseDatum(Liste[i]))[0]; mon := trennedatum(LeseDatum(Liste[i]))[1]; tag := trennedatum(LeseDatum(Liste[i]))[2]; Warum verwendest du nicht einfach eine lokale (string-)Variable um das Ergebnis von LeseDatum() zwischenzuspeichern? |
AW: Dateien kopieren wird langsam.
wow danke sx2008 ...
das hat das proggie jetz schonma enorm beschleunigt, dass ich das nich selbst gesehn hab :-) thx |
AW: Dateien kopieren wird langsam.
aber direkt mal ne andere frage, damit ich keinen neuen thread anfangen muss... das kopieren von vielen datein dauert ja nun ein wenig... wie stellt man es denn an, dass das formular während der for schleife bedienbar bleibt? bzw. habe ich ein label drin, auf dem stehen sollte 45 / 10456 Bilder kopiert. Jedoch erscheint das erst am Ende mit 10456 / 10456 Bilder kopiert.
edit: sehs grad im qt steht ja
Code:
aber selbst wenn ich
Label1.Caption := inttostr(Liste.Count) + ' / ' + inttostr(Liste.Count) + ' Bilder kopiert.';
Code:
schreibe gehts nich ..
Label1.Caption := inttostr(i) + ' / ' + inttostr(Liste.Count) + ' Bilder kopiert.';
|
AW: Dateien kopieren wird langsam.
Zitat:
Code:
komplexere Lösung:
Label1.Caption := inttostr(i) + ' / ' + inttostr(Liste.Count) + ' Bilder kopiert.';
application.processmessages; Auslagerung des Kopiervorgangs in einen separaten Thread |
AW: Dateien kopieren wird langsam.
![]()
Delphi-Quellcode:
Ja, man kann es über
Label1.Caption := Format('%d / %d Bilder kopiert.', [i, Liste.Count]);
Application.ProcessMessages; ![]() wobei sowas aber auch sehr nach der Verwendung eines Threads schreit. |
AW: Dateien kopieren wird langsam.
Zitat:
Häufig ist es aber so, dass der Benutzer auf den Abschluss der Operation (hier: kopieren der Dateien) warten muss, bevor er sinnvoll weiterarbeiten kann. Leider hat Delphi auch keine Multithreading-Gene in Objekt-Pascal selbst mitbekommen, so dass echtes Multithreading immer viel aufwändiger als das primitive Application.ProccessMessages ist. Vom Aufwand/Nutzen Verhältnis her gesehen, würde ich hier keinen Thread benützen. Rein technisch gesehen wäre es aber zumindest interessant, denn Multithreading ist einer der Megatrends der nächsten Jahre. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz