[Erledigt] Dateien zählen
-
- Beiträge: 1062
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
[Erledigt] Dateien zählen
Hi.
Es sollen ausgehend von einem Verzeichnis alle Dateien unter diesem Verzeichnis bearbeitet werden.
Alles ok -- mit FindFirst, FindNext und Konsorten geht das ganz gut.
Mir geht es aber um die Rückmeldung an den Benutzer in der Art von
Bearbeite x von 20000
wobei das X ja kein Problem ist.
Meine Frage: Muss ich den Verzeichnisbaum zweimal durhsuchen? Also einmal um die Dateien zu zählen und ein zweites mal um sie zu bearbeiten?
Oder gibt es eine elegantere/schnellere Methode die Gesamtzahl der zu bearbeitenden Dateien zu ermitteln?
THX
Es sollen ausgehend von einem Verzeichnis alle Dateien unter diesem Verzeichnis bearbeitet werden.
Alles ok -- mit FindFirst, FindNext und Konsorten geht das ganz gut.
Mir geht es aber um die Rückmeldung an den Benutzer in der Art von
Bearbeite x von 20000
wobei das X ja kein Problem ist.
Meine Frage: Muss ich den Verzeichnisbaum zweimal durhsuchen? Also einmal um die Dateien zu zählen und ein zweites mal um sie zu bearbeiten?
Oder gibt es eine elegantere/schnellere Methode die Gesamtzahl der zu bearbeitenden Dateien zu ermitteln?
THX
Zuletzt geändert von charlytango am Fr 12. Mär 2021, 13:47, insgesamt 1-mal geändert.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Dateien zählen
Hi!
Also: Solange Du nicht auf die Idee kommst, die Dateien umzubenennen ist das einfach.
Du klaust das Beispiel aus der fpc documentation https://www.freepascal.org/docs-html/rt ... first.html und baust das um:
Für das Beispiel brachst Du dann noch ne ListBox auf Deinem Formular.
Das war's!
Winni
Also: Solange Du nicht auf die Idee kommst, die Dateien umzubenennen ist das einfach.
Du klaust das Beispiel aus der fpc documentation https://www.freepascal.org/docs-html/rt ... first.html und baust das um:
Code: Alles auswählen
Uses .......,SysUtils;
Procedure Example43;
Var Info : TSearchRec;
Count : Longint;
s : string;
Begin
Count:=0;
If FindFirst ('*',faAnyFile,Info)=0 then
begin
Repeat
Inc(Count);
With Info do
begin
s := IntToStr(Count) + #32;
If (Attr and faDirectory) = faDirectory then
s := s+ 'Dir: ';
s := s + name +#32+IntToStr(size);
ListBox1.Items.add(s);
ListBox1.TopItem := ListBox1.Count - 10;
application.ProcessMessages;
s:= '';
FileBearbeiten(name); // <== Hier kommst Du
end;
Until FindNext(info)<>0;
FindClose(Info);
end;
showMessage ('Finished search. Found ' +IntToStr(Count),' matches');
End;
Für das Beispiel brachst Du dann noch ne ListBox auf Deinem Formular.
Das war's!
Winni
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1647
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Dateien zählen
Ich schätze du musst wirklich zweimal durch.
Aber einfach nur die Dateien ermitteln und zählen geht recht pronto, da diese ja nicht geöffnet werden müssen.
Rekursive Lösung
hat bei mir für ein komplettes Lazarus Verzeichnis 484 Ticks benötigt.
Aber einfach nur die Dateien ermitteln und zählen geht recht pronto, da diese ja nicht geöffnet werden müssen.
Rekursive Lösung
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, EditBtn, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
DirectoryEdit1: TDirectoryEdit;
lbDirs: TLabel;
lbFiles: TLabel;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var dirs, files : integer;
start : int64;
procedure CountFiles(path : string; var dirs, files : integer);
var sr : TSearchRec;
i : integer;
begin
i := FindFirst(path + DirectorySeparator + AllFilesMask, faAnyFile, sr);
while (i = 0) do
begin
if (sr.name <> '.') and (sr.Name <> '..') then
begin
if (sr.Attr and faDirectory <> 0) then
begin
inc(dirs);
CountFiles(path + DirectorySeparator + sr.Name, dirs, files);
end else
begin
inc(files);
end;
end;
i := FindNext(sr);
end;
FindClose(sr);
end;
begin
Start := GetTickCount64;
dirs := 0;
files := 0;
CountFiles(DirectoryEdit1.Directory, dirs, files);
lbDirs.Caption := dirs.toString;
lbFiles.Caption := files.toString;
ShowMessage(Format('needed %d Ticks', [GetTickCount64 - start]));
end;
end.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Dateien zählen
@fliegermichl
Ich hatte sein Problem nicht derart verstanden, dass er den gesamten file tree braucht, sondern eher so, wie er pro Datei eine Rückmeldung bekommt.
Aber das müsste er eklären.
Winni
Ich hatte sein Problem nicht derart verstanden, dass er den gesamten file tree braucht, sondern eher so, wie er pro Datei eine Rückmeldung bekommt.
Aber das müsste er eklären.
Winni
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1647
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Dateien zählen
@winni
Die Frage war doch eigentlich recht eindeutig.
Er möchte eine Meldung anzeigen "Bearbeite Datei x von y".
x war klar, y fehlte. Also muss er zuerst die Anzahl der zu bearbeitenden Dateien ermitteln.
Gruß
Michael
Die Frage war doch eigentlich recht eindeutig.
Er möchte eine Meldung anzeigen "Bearbeite Datei x von y".
x war klar, y fehlte. Also muss er zuerst die Anzahl der zu bearbeitenden Dateien ermitteln.
Gruß
Michael
-
- Beiträge: 1062
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Dateien zählen
@winni
@fliegermichl
erstmal danke bisher.
Es ging tatsächlich NUR um das Zählen der Dateien und die Laufzeitoptimierung dieser Aktion.
Und natürlich soll der Wert auch stimmen damit man bei der eigentlichen Bearbeitung der Dateien sauber runter zählen kann.
mp3tag - ein Programm zur Bearbeitung von diversesten Tags in Multimediadateien verwendet z.B. so etwas.
Ich war nur immer erstaunt von dem Tempo in dem die Meldung "bearbeite X von 6728" kommt.
Irgendwoher muss die Gesamtzahl der Dateien ja kommen und das noch dazu praktisch gleich nach dem entsprechenden Tastendruck. Jedenfalls sauschnell.
Als Info nehme ich mal mit dass ich da zweimal drüber muss -- sofern nicht noch jemand etwas besseres einfällt
@fliegermichl
erstmal danke bisher.
Es ging tatsächlich NUR um das Zählen der Dateien und die Laufzeitoptimierung dieser Aktion.
Und natürlich soll der Wert auch stimmen damit man bei der eigentlichen Bearbeitung der Dateien sauber runter zählen kann.
mp3tag - ein Programm zur Bearbeitung von diversesten Tags in Multimediadateien verwendet z.B. so etwas.
Ich war nur immer erstaunt von dem Tempo in dem die Meldung "bearbeite X von 6728" kommt.
Irgendwoher muss die Gesamtzahl der Dateien ja kommen und das noch dazu praktisch gleich nach dem entsprechenden Tastendruck. Jedenfalls sauschnell.
Als Info nehme ich mal mit dass ich da zweimal drüber muss -- sofern nicht noch jemand etwas besseres einfällt

- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Dateien zählen
@fliegermichl
Okay. Hast gewonnen. Hab ich zu diagonal gelesen.
Das gibt es streng genommen nur eine 2-Pass-Lösung.
Es sei denn, man orientiert sich an den undurchsichtigen Algorithmen von Download-Zeiten.
Oder der "Estimated Time" bei Kopier-Orgien auf externe Festplatten.
Die EST fängt erstmal bei 200 Stunden an. Springt dann auf 2. Und dann wird der timespan immer kleiner.
Oder irgendwelche BitTorrent software, die alles nach dem letzten Durchsatz berechnet. Und dann immer abwechseln eine Restzeit zwischen 5 Minuten und 2 Stunden präsentiert.
Nach dem Motto: Hauptsache der User sieht was.
Da nehmen wir doch einfach mal an, dass durchnittlich 200 Dateien pro Verzeichnis vorhanden sind. Und dann .... Hauptsache der User sieht was.....
Winni
Okay. Hast gewonnen. Hab ich zu diagonal gelesen.
Das gibt es streng genommen nur eine 2-Pass-Lösung.
Es sei denn, man orientiert sich an den undurchsichtigen Algorithmen von Download-Zeiten.
Oder der "Estimated Time" bei Kopier-Orgien auf externe Festplatten.
Die EST fängt erstmal bei 200 Stunden an. Springt dann auf 2. Und dann wird der timespan immer kleiner.
Oder irgendwelche BitTorrent software, die alles nach dem letzten Durchsatz berechnet. Und dann immer abwechseln eine Restzeit zwischen 5 Minuten und 2 Stunden präsentiert.
Nach dem Motto: Hauptsache der User sieht was.
Da nehmen wir doch einfach mal an, dass durchnittlich 200 Dateien pro Verzeichnis vorhanden sind. Und dann .... Hauptsache der User sieht was.....
Winni
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Dateien zählen
Hi!charlytango hat geschrieben: Do 11. Mär 2021, 21:59
Ich war nur immer erstaunt von dem Tempo in dem die Meldung "bearbeite X von 6728" kommt.
Irgendwoher muss die Gesamtzahl der Dateien ja kommen und das noch dazu praktisch gleich nach dem entsprechenden Tastendruck. Jedenfalls sauschnell.
Als Info nehme ich mal mit dass ich da zweimal drüber muss -- sofern nicht noch jemand etwas besseres einfällt![]()
Der Trick ist, dass einige Software schon mal "heimlich" Buch führt über die Anzahl der Dateien oder sogar den Inhalt ganzer Vereichnisse. Die Starten bevor Du die erste Taste gedrückt hast schon mal ein paar Threads - was die Hardware so hergibt - im Hintergrund und die durchforstet alle in Frage kommende Verzeichnisse. Und die hast Du ja entweder in den Einstellungen hinterlassen oder er weiss es von der letzten Session. Und Du wunderst Dich, dass das Biest soviel Speicher benötigt ...
Winni
Re: Dateien zählen
Wenn man wirklich mit lange andauernder Zählerei rechnen muss, könnte man auch beim Bearbeitungsstart gleichzeitig einen separaten Thread starten welcher das Zählen übernimmt.
Anfänglich würde man dann nur ein Lebenszeichen anzeigen, wie z.B. die Zahl der bearbeiteten Dateien (x) und sobald der Thread fertig ist, könnte man die Anzeige auf x-von-y oder Prozent umschalten.
So würde ich das vielleicht machen, damit die Bearbeitung gleich los geht.
Anfänglich würde man dann nur ein Lebenszeichen anzeigen, wie z.B. die Zahl der bearbeiteten Dateien (x) und sobald der Thread fertig ist, könnte man die Anzeige auf x-von-y oder Prozent umschalten.
So würde ich das vielleicht machen, damit die Bearbeitung gleich los geht.
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Dateien zählen
Hi!charlytango hat geschrieben: Do 11. Mär 2021, 21:59
Ich war nur immer erstaunt von dem Tempo in dem die Meldung "bearbeite X von 6728" kommt.
Irgendwoher muss die Gesamtzahl der Dateien ja kommen und das noch dazu praktisch gleich nach dem entsprechenden Tastendruck. Jedenfalls sauschnell.
Ich hab mal den findfirst/findnext/findclose Ansatz übernommen und auf reines Zählen reduziert.
Für das Verzeichnis lazarus mit allen Unterverzeichnissen ergibt das:
14849 Datein in 353 Millisekunden
Das wäre dann 1/3 Sekunde nach dem Tastendruck.
Jetzt brauchen wir von charlytango noch eine genaue Definition von "sauschnell".
Source folgt. Windows User müssen die const "StartDirectory" anpassen.
Code: Alles auswählen
var DirAttr : integer;
function Tree (StartDir : String) : integer;
var search : TSearchRec;
begin
{$IFDEF LINUX} DirAttr := 48;
{$ELSE} DirAttr := faDirectory;
{$ENDIF}
result := 0;
if startDir[length(startDir)] <> DirectorySeparator then
startDir := startDir + DirectorySeparator;
if findFirst(startDir+'*',faAnyFile,search) = 0 then
begin
repeat
if (search.name = '.') or (search.name = '..') then Continue;
if (search.Attr = DirAttr) then result := result + Tree(startDir+search.Name) else
inc (result);
until FindNext(search) <> 0;
end;
findClose(search);
end;
procedure TForm1.Button9Click(Sender: TObject);
const startDirectory = '/usr/lib64/lazarus/';
var filenum : Integer;
StartTime, EndTime : QWord;
begin
StartTime := GetTickCount64;
fileNum := tree(startDirectory);
EndTime := GetTickCount64;
showMessage (IntToStr(fileNum)+' Dateien in '+LineEnding +
IntToStr (EndTime-StartTime)+' ms' );
end;
Grüße
Winni
Re: Dateien zählen
@Winni: Kommt halt auch aufs Medium und evtl. aufs Dateisystem an.
Ich habe z.B. rund 200GB Musik auf einer externen HD (FAT32).
Da dauert das auslesen der ID3 Tags schon etwas länger (30 Minuten).
Ich bin mir aber nicht sicher, wie das mit dem reinen Zählen ist.
Bekommt man das nicht relativ direkt z.B. aus der "File Allocation Table"?
Kennt sich da jemand aus?
Ich habe z.B. rund 200GB Musik auf einer externen HD (FAT32).
Da dauert das auslesen der ID3 Tags schon etwas länger (30 Minuten).
Ich bin mir aber nicht sicher, wie das mit dem reinen Zählen ist.
Bekommt man das nicht relativ direkt z.B. aus der "File Allocation Table"?
Kennt sich da jemand aus?
-
- Beiträge: 1062
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Dateien zählen
Oh, habe ich da irgendwie einen Ehrgeiz gekitzeltWinni hat geschrieben: Fr 12. Mär 2021, 12:57
14849 Datein in 353 Millisekunden
Das wäre dann 1/3 Sekunde nach dem Tastendruck.
Jetzt brauchen wir von charlytango noch eine genaue Definition von "sauschnell".

Aber DANKE gleich fürs Testen denn das wollte ich entspannt am Wochenende machen.
Die 1/3 Sekunde kann wohl schon als sauschnell klassifiziert werden.
ich mag das Klima hier im Forum -- und auch die fachliche Expertise
nochmals herzlichsten Dank - case closed
Re: [Erledigt] Dateien zählen
jetzt könnte man nochmal mit FindAllFiles vergleichen...
https://wiki.freepascal.org/FindAllFiles
https://wiki.freepascal.org/FindAllFiles
Gruß, Michael
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Dateien zählen
Ich hatte mal gelesen, dass die Dateisuche schneller geht, wenn man erst ein komplettes Verzeichnis durch iteriert und erst danach in die Unterverzeichnisse absteigt.theo hat geschrieben: Fr 12. Mär 2021, 13:35 @Winni: Kommt halt auch aufs Medium und evtl. aufs Dateisystem an.
Ich habe z.B. rund 200GB Musik auf einer externen HD (FAT32).
Da dauert das auslesen der ID3 Tags schon etwas länger (30 Minuten).
Ich bin mir aber nicht sicher, wie das mit dem reinen Zählen ist.
Bekommt man das nicht relativ direkt z.B. aus der "File Allocation Table"?
Kennt sich da jemand aus?
Das hängt mit Sicherheit an den Zugriffsmustern des Mediums und Datenstrukturen des Dateiystems zusammen.
Bei einer HDD hast du typischerweise einen Read-Ahead, der weitere Daten nach den angeforderten Daten bereits im Dateisystemcache des Betriebssystems lädt. Ist an dieser Position das selbe Verzeichnis abgelegt, kannst du dieses schneller auslesen als ein Unterverzeichnis, das an ganz anderer Stelle auf der Scheibe gespeichert ist.
Bei SSDs spielt das technisch bedingt nur eine untegordnete Rolle.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: [Erledigt] Dateien zählen
Hi!
ID Tags: Dazu müssen die Dateien jeweils angefasst werden. Bei ID3v1 geht das noch recht einfach: es sind die letzten 128 Bytes der Datei. Bei den modernerneren Tags ist es komplexer.
Look ahead und Buffer: Selbst Windows puffert inzwischen look ahead Daten. Linux macht das schon ewig, allen ungenutzten RAM für die Buffers zu reservieren. Den Effekt kann man z.B. derart vorführen:
Man macht ein "find" über das gesamte Dateisystem. Das dauert. Dabei zieht er sich aber alle Verzeichnisse in die Buffers. Wenn man jetzt wieder ein find eingiebt - auch mit einem anderen Suchbegriff - geht das "sauschnell".
Natürlich kommt es auf das Dateisystem an: fat16,fat32, extfat sind ziemlich dumm und langsam.
ext2/3/4 sind schneller; NTFS auch.
Soviel ich weiss, hält kein Dateisystem die Anzahl der benutzten Dateien pro Verzeichnis vorrätig: kann man ja zählen.
Und natürlich kommt es auf die Hardware an. Mach das mal mit ner Festplatte von 1990 - falls Du noch irgenwo nen IDE Port hast. Da kannst Du Kaffee kochen gehen!
Und so betrachtet sind SDDs ein echter Fortschritt. Bis zu dem Tag, an dem man dort Daten retten muss. Da ist es dann oft eiin Totalschaden.
Winni
ID Tags: Dazu müssen die Dateien jeweils angefasst werden. Bei ID3v1 geht das noch recht einfach: es sind die letzten 128 Bytes der Datei. Bei den modernerneren Tags ist es komplexer.
Look ahead und Buffer: Selbst Windows puffert inzwischen look ahead Daten. Linux macht das schon ewig, allen ungenutzten RAM für die Buffers zu reservieren. Den Effekt kann man z.B. derart vorführen:
Man macht ein "find" über das gesamte Dateisystem. Das dauert. Dabei zieht er sich aber alle Verzeichnisse in die Buffers. Wenn man jetzt wieder ein find eingiebt - auch mit einem anderen Suchbegriff - geht das "sauschnell".
Natürlich kommt es auf das Dateisystem an: fat16,fat32, extfat sind ziemlich dumm und langsam.
ext2/3/4 sind schneller; NTFS auch.
Soviel ich weiss, hält kein Dateisystem die Anzahl der benutzten Dateien pro Verzeichnis vorrätig: kann man ja zählen.
Und natürlich kommt es auf die Hardware an. Mach das mal mit ner Festplatte von 1990 - falls Du noch irgenwo nen IDE Port hast. Da kannst Du Kaffee kochen gehen!
Und so betrachtet sind SDDs ein echter Fortschritt. Bis zu dem Tag, an dem man dort Daten retten muss. Da ist es dann oft eiin Totalschaden.
Winni