Alle Dateien finden: Problem der Endlosschleife
Alle Dateien finden: Problem der Endlosschleife
Ich versuche ausgehend von einem Startordner alle Dateien inkl. der Dateien in den Unterordnern zu finden. Dazu habe ich FindAllFiles benutzt. Das Problem ist, dass FindAllFiles auch symbolischen Links folgt, die letztlich zu einer unendlichen Schleife führen können (zum Beispiel dann, wenn in einem Unterordner ein symbolischer Link auf einen Elternordner zu finden ist). Soweit ich recherchiert habe, kann FreePascal/Lazarus plattformunabhängig nicht zwischen Ordnern und symbolischen Links auf Ordner unterscheiden. Auch ChatGPT konnte mir keine Lösung vorschlagen. Gibt es tatsächlich keine Möglichkeit, plattformunabhängig alle Dateien zu finden, ohne eventuell in eine Endlosschleife zu geraten?
Re: Alle Dateien finden: Problem der Endlosschleife
Hallo,
du müsstest sehr wahrscheinlich eine entsprechende Find-Funktion selbst implementieren und dabei manuell überprüfen, ob es sich bei den gefundenen Elementen um einen symbolischen Link handelt.
Auf StackOverflow wurden verschiedene Ansätze, Symlinks in Pascal ausfindig zumachen, zusammengetragen. Ich habe keinen davon getestet, aber vielleicht hilft es dir ja: https://stackoverflow.com/questions/137 ... freepascal
du müsstest sehr wahrscheinlich eine entsprechende Find-Funktion selbst implementieren und dabei manuell überprüfen, ob es sich bei den gefundenen Elementen um einen symbolischen Link handelt.
Auf StackOverflow wurden verschiedene Ansätze, Symlinks in Pascal ausfindig zumachen, zusammengetragen. Ich habe keinen davon getestet, aber vielleicht hilft es dir ja: https://stackoverflow.com/questions/137 ... freepascal
-
- Beiträge: 6956
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Alle Dateien finden: Problem der Endlosschleife
Evtl. mit FindFirst und FindNextdu müsstest sehr wahrscheinlich eine entsprechende Find-Funktion selbst implementieren und dabei manuell überprüfen, ob es sich bei den gefundenen Elementen um einen symbolischen Link handelt.
https://www.freepascal.org/docs-html/rt ... first.html
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: Alle Dateien finden: Problem der Endlosschleife
Vielen Dank für die Tipps, die aber (meiner Meinung nach) das Problem leider nicht lösen. Ich werde deshalb jetzt ein Shell-Script (für Linux) bzw. eine Batch-Datei (für Windows) erstellen, die die gefundenen Dateien in eine Textdatei schreiben. Mit TProcess führe ich das Sript aus und lese dann die Textdatei ein. Das ist sicherlich nicht elegant, hilft mir aber vermutlich weiter.
- Jorg3000
- Lazarusforum e. V.
- Beiträge: 385
- Registriert: So 10. Okt 2021, 10:24
- OS, Lazarus, FPC: Win64
- Wohnort: NRW
Re: Alle Dateien finden: Problem der Endlosschleife
Hi!
Ich hatte das Problem zwar noch nicht, aber nun habe ich mal folgende Zeile in meine Funktion mit einer FindFirst/FindNext-Schleife eingebaut.
Ich hoffe, dass das Problem damit erledigt sein sollte, oder?
Grüße, Jörg
Ich hatte das Problem zwar noch nicht, aber nun habe ich mal folgende Zeile in meine Funktion mit einer FindFirst/FindNext-Schleife eingebaut.
Code: Alles auswählen
if (not AcceptSymLinks) and (SearchRec.Attr and faSymLink = faSymLink) then Continue;
Grüße, Jörg
Re: Alle Dateien finden: Problem der Endlosschleife
Warum denkst du, dass das dein Problem nicht löst?Oli hat geschrieben: So 28. Jul 2024, 16:40 Vielen Dank für die Tipps, die aber (meiner Meinung nach) das Problem leider nicht lösen.
Ich würde eine rekursive Funktion schreiben, die einen Ordner und die Suchmaske als Parameter übergeben bekommt und ein Array mit den absoluten Dateipfaden der Treffer zurückgibt.
Findet die Funktion einen Unterordner, wird überprüft, ob der Unterordner ein symbolischer Link ist (wie das geht, findest du auf Stackoverflow), und falls ja, ruft die Funktion sich mit dem Unterordner selbst auf und fügt die Ergebnisse dem Array hinzu.
Hier ein rudimentärer Aufbau der Funktion (halb Pascal, halb Pseudocode

Code: Alles auswählen
function FindInFilesWithoutSymlink(entrypath: String; pattern: String): Array of String
begin
{Die Logik für das Finden hier implementieren}
For file in GefundeneErgebnisse do
begin
if (file is NormalFile) and FileNameMatchesWithPattern then
{Ergebnisse dem Array hinzufügen}
begin
SetLength(Result, Length(Result)+1)
Result[Length(Result)-1] = GefundenerDateiPfad
end
else if file is FolderNotSymlink then
Result := Result + FindInFilesWithoutSymlink(GefundenerOrdner, pattern);
end;
Re: Alle Dateien finden: Problem der Endlosschleife
Vielen Dankfür die weiteren Hinweise. Auch mit FindFirst und FindNext lässt sich meiner Meinung nach das Problem nicht lösen, solange faSymLink nicht portabel ist. Ich habe (unter Linux) folgendes versucht: Zuerst erstelle ich mittels eines Shell-Skript drei Ordnet mit Dateien und symbolischen Links:
Die symbolischen Links verweisen von tmp1 auf tmp2 und umgekehrt. Wenn ich das nachstehende Programm ausführe, kommt es zu einer Endlosschleife.
Eine Prüfung mit faSymLink auf symbolische Links ist leider nicht portable (Versionen Lazarus 2.2.0, FPC 3.2.2), also nicht unabhängg vom Betriebssystem. Als Hilfslösung führe ich in meinem Pascal-Programm das folgende Shell-Skript (Linux) aus, das alle Dateien in eine Textdatei schreibt (für Windows mache ich prinzipiell das gleiche mit einer Batch-Datei).
Code: Alles auswählen
#!/bin/bash
mkdir ~/tmp1
mkdir ~/tmp2
mkdir ~/tmp1/tmp11
touch ~/tmp1/a.txt
touch ~/tmp1/b.txt
touch ~/tmp1/tmp11/c.txt
touch ~/tmp2/d.txt
cd
ln -s ~/tmp2/ ~/tmp1/Link_zu_tmp2
ln -s ~/tmp1/ ~/tmp2/Link_zu_tmp1
Code: Alles auswählen
program project1;
uses
Classes,
SysUtils,
Strutils;
procedure Suchen(Ordner:String);
// Sucht rekursiv alle Dateien,
// beginnend mit Ordner
var
Info : TSearchRec;
Ordner2 : String;
OrdnerNeu : String;
begin
Ordner2 := Ordner + PathDelim + '*';
If FindFirst (Ordner2,faAnyFile,Info)=0 then
begin
Repeat
With Info do
begin
If (Attr and faDirectory) = faDirectory then
begin
if (Name <> '.') and (Name <> '..') then
begin
Writeln('Ordner:'+ Ordner + PathDelim + Name);
Suchen(Ordner + PathDelim + Name);
end;
end
else
Writeln('Datei:'+ Name);
end;
Until FindNext(info)<>0;
FindClose(Info);
end;
end;
begin
Suchen('/home/oliver/tmp1');
Writeln ('Finished');
end.
Code: Alles auswählen
#!/bin/bash
#find.sh Startordner Ausgabedatei
exec 2>/dev/null
/usr/bin/find $1 -type f >> $2
-
- Beiträge: 6956
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Alle Dateien finden: Problem der Endlosschleife
Was eine Möglichkeit wäre, mit FindFirst/FindNext einzulesen und vor zu prüfen, ob es ein Link ist, wen ja, dan keine Rekursivität.Soweit ich recherchiert habe, kann FreePascal/Lazarus plattformunabhängig nicht zwischen Ordnern und symbolischen Links auf Ordner unterscheiden.
Versuche mal dies hier.
Hat mit ChatGPT in einer C-Version gegeben, welche ich umgeschrieben habe.
Der Testlauf funktionierte.
Code: Alles auswählen
program Project1;
uses
SysUtils,
unix,
BaseUnix;
procedure Test(path: PChar);
var
filestat: Stat;
begin
if fpLstat(path, @filestat) = -1 then begin
WriteLn('lstat');
end;
if fpS_ISREG(filestat.st_mode) then begin
WriteLn('normale Datei');
end else if fpS_ISDIR(filestat.st_mode) then begin
WriteLn('Ordner');
end else if fpS_ISLNK(filestat.st_mode) then begin
WriteLn('S-Link');
end else begin
WriteLn('Anderer Typ');
end;
end;
begin
Test('/home/tux/Schreibtisch/filestest/main.c'); // nornal
Test('/home/tux/Schreibtisch/filestest/test'); // Ordner
Test('/home/tux/Schreibtisch/filestest/test.c'); // Link
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 18
- Registriert: Mo 8. Apr 2013, 17:12
- OS, Lazarus, FPC: Win11, Debian 12.5, Lazarus: 2.2.6, FPC: 3.2.2
- CPU-Target: 64Bit
Re: Alle Dateien finden: Problem der Endlosschleife
Aus https://build.alb42.de/fpcbin/docu/html ... first.html
LgfaSymlink - Report symlinks instead of following them
[...]
Since faSymlink is not included in faAnyFile, to find all possible files and symlinks you need to call FindFirst so:
Code: Alles auswählen
if FindFirst('*', faAnyFile or faSymLink, info)=0 then
Re: Alle Dateien finden: Problem der Endlosschleife
Nochmals Danke für Eure Antworten. Mathias' Lösung funktioniert unter Linux einwandfrei, das werde ich mir gerne merken. Da ich allerdings auch unter Windows eine Lösung brauche, behelfe ich mir wie oben beschrieben mit Shell- und Batch-Skripten. Ich denke, mit den Lösungsvorschlägen können wir meine Frage als ausreichend beantwortet sehen. Vielen Dank.
-
- Beiträge: 6956
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Alle Dateien finden: Problem der Endlosschleife
Da ich allerdings auch unter Windows eine Lösung brauche.Oli hat geschrieben: Di 30. Jul 2024, 22:36 Nochmals Danke für Eure Antworten. Mathias' Lösung funktioniert unter Linux einwandfrei, das werde ich mir gerne merken. Da ich allerdings auch unter Windows eine Lösung brauche, behelfe ich mir wie oben beschrieben mit Shell- und Batch-Skripten. Ich denke, mit den Lösungsvorschlägen können wir meine Frage als ausreichend beantwortet sehen. Vielen Dank.
Mach es doch auf diese Art:
Code: Alles auswählen
{$IFDEF Linux}
sdl3_lib = 'SDL3';
{$ENDIF}
{$IFDEF Windows}
sdl3_lib = 'SDL3.dll';
{$ENDIF}
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
- Zvoni
- Beiträge: 396
- Registriert: Fr 5. Jul 2024, 08:26
- OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
- CPU-Target: 32Bit
- Wohnort: BW
Re: Alle Dateien finden: Problem der Endlosschleife
Workaround-Versuch: Sammel erst alle Ergebnisse die ausschliesslich Ordner sind --> https://lazarus-ccr.sourceforge.io/docs ... ories.html
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.