![]() |
Code Optimierung
Hallo DP!
Ich habe einen Algorithmus geschrieben um Datein in einem angegebenen Verzeichnis und Unterverzeichnissen zu Suchen. Der Code Funktioniert sehr gut, aber wenn es eine hohe Anzahl an dateien ist (>2000) dauert es sehr sehr lange (>10 min bei XP2100+, ATA133 HDD) bis alles durchsucht wurde.
Code:
Meine Frage: Hat jemand eine Idee wie den Code schneller machen kann?
procedure GetFilesInDirectoryMP3(ADirectory: string; AMask: String; ARekursiv: Boolean);
var SR: TSearchRec; Value, M, S : Integer; begin if (ADirectory<>'') and (ADirectory[length(ADirectory)]<>'\') then ADirectory:=ADirectory+'\'; if (FindFirst(ADirectory+AMask,faAnyFile-faDirectory,SR)=0) then begin repeat if (SR.Name<>'.') and (SR.Name<>'..') and (SR.Attr<>faDirectory) then //ID3Tags, speichern ... einfügen MP3.Execute(ADirectory+SR.Name); if MP3.ID3v2TLEN<>'' then begin Value := Trunc(strtoint(mp3.ID3v2TLEN) / 1000); M := (value mod 3600) div 60; S := (value mod 3600) mod 60; end else begin Value := Trunc(mp3.spielzeit); M := (value mod 3600) div 60; S := (value mod 3600) mod 60; end; mp3liste.Artist:='+ '+MP3.ID3v2TPE1; mp3liste.Album:=MP3.ID3v2TALB; mp3liste.Titel:=MP3.ID3v2TIT2; mp3liste.Genre:=mp3.ID3v2TCON; mp3liste.Zeit:=Format('%2.2d:%2.2d', [M, S]); mp3liste.TrackNr:=MP3.ID3v2TRCK; mp3liste.Dateiname:=SR.Name; mp3liste.Pfad:=ADirectory; write(f3,mp3liste); until FindNext(SR)<>0; FindClose(SR); end; // Unterverzeichnis durchsuchen if ARekursiv then if (FindFirst(ADirectory+'*.*',faDirectory,SR)=0) then begin repeat if (SR.Name<>'.') and (SR.Name<>'..') then GetFilesInDirectoryMP3(ADirectory+SR.Name,AMask,True); until FindNext(SR)<>0; FindClose(SR); end; end; |
Re: Code Optimierung
Delphi-Quellcode:
...
//ID3Tags, speichern ... einfügen if (SR.Name<>'.') and (SR.Name<>'..') and (SR.Attr<>faDirectory) then MP3.Execute(ADirectory+SR.Name); if MP3.ID3v2TLEN<>'' then Value := Trunc(strtoint(mp3.ID3v2TLEN) / 1000); else Value := Trunc(mp3.spielzeit); M := (value mod 3600) div 60; S := (value mod 3600) mod 60; mp3liste.Artist:='+ '+MP3.ID3v2TPE1; mp3liste.Album:=MP3.ID3v2TALB; mp3liste.Titel:=MP3.ID3v2TIT2; mp3liste.Genre:=mp3.ID3v2TCON; mp3liste.Zeit:=Format('%2.2d:%2.2d', [M, S]); mp3liste.TrackNr:=MP3.ID3v2TRCK; mp3liste.Dateiname:=SR.Name; mp3liste.Pfad:=ADirectory; write(f3,mp3liste); ... end; diesen teil solltest du später erledigen, d.h. estmal alle dateien suchen, die du brauchst, diese in eine stringlist schreiben und dann später verarbeiten, gerade das write wird viel zeit in anspruch nehmen |
Re: Code Optimierung
Zitat:
statt: datei suchen --> bearbeiten --> Datei speichern --> Nächste Datei so: datei suchen --> In Stringlist schmeißen --> Nächste Datei --> Stringlist auslesen --> bearbeiten --> Datei Speichern --> Nächste Datei der Stringlist Die ersten 3 Schritte wären ja schneller aber danach muss ich ein 2. mal jede einzelne Datei öffnen und die Tags auslesen. Oder hab ich das falsch verstanden? :gruebel: |
Re: Code Optimierung
naja, aber zb winamp machts ja so:
erstmal nur einlesen... die tags kommen erst wenn man sie auch abspielt/sie in der playlist sieht das könntest du auch machen dann brauch es zwar insgesamt länger, aber der user merkt es nicht...das is der trick |
Re: Code Optimierung
Ich kann die daten (ID3Tags) nicht erst in der Playlist auslesen. Dadurch würden andere Dinge nicht mehr funktionieren. Beim erstellen der MP3 Liste muss einiges ausgelesen und gespeichert werden. Das ist mein Problem sonst hätt ich das schon per Playlist im WinAmp oder MediaPlayer Style gemacht.
|
Re: Code Optimierung
also ich habs bei meinem player so gemacht:
+ files in liste einfügen + anschliessend thread starten, der die ID3 infos ausliest und gleich die liste aktualisiert hat auch den vorteil, dass der player gleich voll funktionsfähig ist, da der thread alles im hintergrund erledigt (nidriegste Priorität!) musst nur aufpassen, wenn der thread noch aktualisiert und du an der liste was veränderst (speziell löschen von einträgen) gruss, iaby |
Re: Code Optimierung
Moin TheReaper,
diese Abfrage
Delphi-Quellcode:
ist aber gefährlich, denn sobald auch ein anderes Attribut, zusätzlich zum Attribut Directory enthalten ist, ist die Bedingung erfüllt.
SR.Attr<>faDirectory
Besser ist gezielt das Attribut abzufragen
Delphi-Quellcode:
(SR.Attr and faDirectory) = 0
|
Re: Code Optimierung
Ich hab mittlerweile rausgefunden warum das so lange dauerte. Beim Auslesen eines Tags von einer bestimmten Datei war eine Schleife die fast Endlos war. Warum? Keine Ahnung :gruebel:. Mit anderen Playern ging das ohne Probs und mit nem Program zum ID3Tags auslesen gabs auch keine Probs. Ich hab den Code etwas optimiert und für alle die es interessiert Hier isser: :-D
Code:
Wenn einer ne Idee hat diesen Code noch besser zu machen dann soll er es bitte nicht für sich behalten. :wink:
...
var Pfad array of string; ... procedure GetFilesInDirectoryMP3(ADirectory: string; AMask: String; ARekursiv: Boolean); var SR: TSearchRec; begin if (ADirectory<>'') and (ADirectory[length(ADirectory)]<>'\') then ADirectory:=ADirectory+'\'; if (FindFirst(ADirectory+AMask,faAnyFile-faDirectory,SR)=0) then begin repeat if (SR.Name<>'.') and (SR.Name<>'..') and ((SR.Attr and faDirectory) = 0) then Setlength(Pfad,length(Pfad)+1); Pfad[high(Pfad)]:=ADirectory+SR.Name; until FindNext(SR)<>0; FindClose(SR); end; if ARekursiv then if (FindFirst(ADirectory+'*.*',faDirectory,SR)=0) then begin repeat if (SR.Name<>'.') and (SR.Name<>'..') then GetFilesInDirectoryMP3(ADirectory+SR.Name,AMask,True); until FindNext(SR)<>0; FindClose(SR); end; end; procedure Tfrm2wnl.BitBtn1Click(Sender: TObject); var i:integer; Value, M, S : Integer; begin seek(f3,filesize(f3)); getfilesindirectoryMP3(directorylistbox1.Directory,'*.mp3' ,true); if high(pfad)>=1 then frm2wnl.progressbar1.Max:=high(pfad); for i:=0 to high(pfad) do begin if Uppercase(ExtractFileExt(pfad[i]))<>'.MP3' then Continue; MP3.Execute(pfad[i]); if MP3.ID3v2TLEN<>'' then Value := Trunc(strtoint(mp3.ID3v2TLEN) / 1000) else Value := Trunc(mp3.spielzeit); M := (value mod 3600) div 60; S := (value mod 3600) mod 60; if MP3.ID3v2TPE1<> '' then mp3liste.Artist:='+ '+MP3.ID3v2TPE1 //Das mit dem '+' passt schon. Einfach ignorieren. else mp3liste.Artist := '+ Unbekannt'; if MP3.ID3v2TALB<> '' then mp3liste.Album:=MP3.ID3v2TALB else mp3liste.Album := 'Unbekannt'; if MP3.ID3v2TIT2<> '' then mp3liste.Titel:=MP3.ID3v2TIT2 else mp3liste.Titel := 'Unbekannt'; if mp3.ID3v2TCON<> '' then mp3liste.Genre:=mp3.ID3v2TCON else mp3liste.Genre := 'Unbekannt'; mp3liste.Zeit:=Format('%2.2d:%2.2d', [M, S]); if MP3.ID3v2TRCK<> '' then mp3liste.TrackNr:=MP3.ID3v2TRCK else mp3liste.TrackNr := '00'; if fileexists (pfad[i]) then begin mp3liste.Dateiname:=ExtractFileName(Pfad[i]); mp3liste.Pfad:=ExtractFilePath(Pfad[i]); end; write(f3,mp3liste); frm2wnl.progressbar1.position:=i; end; ... end; |
Re: Code Optimierung
Delphi-Quellcode:
brauchst du eigentlich nicht, da du ja sowieso nach mp3's suchst...
if Uppercase(ExtractFileExt(pfad[i]))<>'.MP3' then Continue;
Delphi-Quellcode:
getfilesindirectoryMP3(directorylistbox1.Directory,'*.mp3' ,true);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:12 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