![]() |
suche Funktion FindLastDir
suche eine Funktion, die mir ausgehend von einem Pfad , in dem weitere Unterverzeichnisse sind, immer tiefer ins erste "erreichbare"** Unterverzeichnis geht bis keines mehr vorhanden ist und mir den "tiefsten" Pfad zurückliefert.
** der erste Ordner,alphabetisch wie im Windows-Explorer Jemand ne Idee oder Ansatz? Gruß, bluescreen25 |
Re: suche Funktion FindLastDir
|
Re: suche Funktion FindLastDir
Zitat:
Dachte eher an sowas nur umgekehrt...:
Delphi-Quellcode:
function GetAudioplayerDirectory(const APath: String): String;
var i: Integer; begin Result:=APath; i:=Length(APath); If i>3 Then Begin Repeat Dec(i); Until (APath[i] = '\') OR (i=1); If APath[i]='\' Then Result:=Copy(APath,1,i); End end; |
Re: suche Funktion FindLastDir
|
Re: suche Funktion FindLastDir
Zitat:
Ich habe C:\Ordner1 und am Ende möchte ich C:\Ordner1\UnterOrdner1\UnterOrdner1... haben, sprich den letzten und im ersten Moment unbekannten Pfad. Falls es noch UnterOrdner 2 oder mehr gibt, sind diese unberücksichtigt. Immer nur solange in den ersten verfügbaren Ordner springen bis es nicht tiefer geht und dann den vollen Pfad ausgeben. Gruß, bluescreen25 |
Re: suche Funktion FindLastDir
Das kannst du recht einfach mit FindFirst ohne Rekursion erledigen.
Einfach FindFirst mit dem Dateinamen des letzten Aufrufs aufrufen, bis der Rückgabewert <> 0 ist. Als Filter solltest du faDirectory setzen |
Re: suche Funktion FindLastDir
Zitat:
Falls es ein String ist, kannst du dir entweder eine Funktion schreiben, die den String rückwärts nach dem ersten Vorkommen von '\' (oder '/' je nach Fall) durchsucht und einfach mit Copy den Teil von der Position ausgehend rauskopieren oder nach einer "LastPos" Funktion suchen. Falls es das letztere ist, dann sollte der Link die Grundlage bilden, die letzte Ebene eines Verzeichnisses zu finden. |
Re: suche Funktion FindLastDir
Zitat:
Ich nutze schon FindAllFiles, doch in einer ganz anderen Weise, dachte es würde einfacher gehen.... Eigendlich wäre das nur ein Teil des Gesamten, wo in einem MP3Player von einem File ausgehend, ein Ordner abgespielt, am Ende dann aus dem Ordner in die höhere Ebene in den nächsten Ordner gehen soll und das erste File abspielen soll. Natürlich wenn keine Ordner vorhanden, das nächste File in der höheren Ebene. Gruß, bluescreen25 |
Re: suche Funktion FindLastDir
Naja, in dem Fall weißt du ja den Pfad schon fast.
Du brauchst nur den String an Hand der '\' zerlegen, kriegst daraus alle Teile des Pfades und kannst rückwärts auf die einzelnen Teile eine rekursive Verzeichnissuche machen. Wenn es keine Verzeichnisse in einem Pfad mehr gibt, hast du die letzte Ebenen unter einem jeweiligen Teilpfad. |
Re: suche Funktion FindLastDir
Zitat:
c:\MP3\Album1\letzterSong.mp3 c:\MP3 c:\MP3\nächstesAlbum\ggfUnterordner\ggfUnterOrdner \erstesFile.mp3 <-- hier würde ich nur c:\Mp3\nächstesAlbum wissen ,aber den letzten Ordner und sogar daraus das erste File wieder abspielen wollen... hehe...etwas kurios wird aber noch schlimmer: eine gesetzte oberste Grenze (Pfad) erreicht wie c:\MP3 und als letztes c:\MP3\letztesAlbum\letzterOrdner\letztesFile.mp3 soll dann wiedrum beim ersten Ordner anfangen und dort in die Tiefe gehen und da abspielen...und dann der Ablauf von oben weiter....wobei in der Tiefe abgespielt wird, immer eine Ebene höher und zuletzt auf das nächste Album in die Tiefe...bis wieder alles abgespielt wird.... Ist eine Art CD-Wechsler-Funktion , nur das es etwas komplexer ist, wegen Ordner in der Tiefe, was eine normale CD nicht hat wie C:\MP3\Album1\CD1\*.mp3 und das ggf in jedem Ordner darüber noch Restfiles liegen können sprich in ..\Album1 liegt Ordner \CD1 und ggf noch *.mp3. Insgesamt wollte ich die Schritte in einzelne Funktionen aufteilen und dann zusammenstellen... Gruß,bluescreen25 |
Re: suche Funktion FindLastDir
Hi,
Dafür gibts doch schon einen Funktion in der Codelib ich meine die nennt sich ![]() Die liest dir alle Dateien eines Ordners aus und schreibt sie in eine Stringlist und von da an sollte der Rest kein Problem mehr darstellen |
Re: suche Funktion FindLastDir
Zitat:
|
Re: suche Funktion FindLastDir
Warum nur FindFirst? Was ist wenn das Verzeichnis mehrere Unterverzeichnisse hat?
|
Re: suche Funktion FindLastDir
Zitat:
Wie wäre es mit dem ersten Finden des Unterordners verschachtelt diesen wieder als Path in die Funktion zu leiten um wiedrum den ersten Unterordner zu finden, wenn kein UnterOrdner mehr zu finden, dann Rückgabe des letzen Path ? Dann hätte ich schonmal den Pfad. Diesen kann ich dann mit FindAllFiles nach Dateien durchsuchen und abspielen... Ich versuche morgen mal einen Ansatz anzubieten.. Gruß, bluescreen25 |
Re: suche Funktion FindLastDir
Hi,
Ich hab da mal was gebastelt, das sollte wenn wir nicht völlig aneinander vorbeireden in etwa hinkommen. Eigentlich soll man ja keine Lösungen posten, aber trotzdem:
Delphi-Quellcode:
Edit: Absichtlich nicht kommentiert versuch selbst herauszufinden wie und warum, bei Fragen her damit
function FindLastDir(sDirectory : string) : string;
var SearchRec : TSearchRec; begin sDirectory := IncludeTrailingPathDelimiter(sDirectory); result := sDirectory; if FindFirst(sDirectory + '*.*', faDirectory, SearchRec) = 0 then begin try repeat if ((SearchRec.Attr and faDirectory) = faDirectory) and(SearchRec.Name <> '.') and (SearchRec.Name <> '..') then begin result := FindLastDir(sDirectory + SearchRec.Name); break; end; until FindNext(SearchRec) <> 0; finally FindClose(SearchRec); end; end; end; |
Re: suche Funktion FindLastDir
Wow, ansatzweise hatte ich das auch noch so hinbekommen, scheiterte an Einzelheiten...zumindest bin ich jetzt in der Lage, weitere Teilfunktionen zu erstellen, ich denke, ich habs verstanden...
Vielen Dank.. :-D Zitat:
|
Re: suche Funktion FindLastDir
Zitat:
Angenommen ich habe einen Verzeichnisbaum der so aussieht, Zitat:
Delphi-Quellcode:
FindLastDir('C:\Ebene1')
Code:
Daraus folgt der Rückgaberwert der Funktion ist immer der im letzten Aufruf ermittelt String.
Dann sieht Result so aus:
1. Aufruf: 1. Zuweisung: result = 'C:\Ebene1\' 2. Aufruf: 1. Zuweisung: result = 'C:\Ebene1\Ebene2\' 3. Aufruf: 1. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\' 2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\' 4. Aufruf: 1. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\' // --> 2.Zuweisung wir nicht ausgeführt! kehrt zurück zum 3. Aufruf: 2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\' break; kehrt zurück zum 2. Aufruf: 2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\' break; kehrt zurück zum 1. Aufruf: 2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\' break; kehrt zurück zu Deinem Aufruf, du erhälst: 'C:\Ebene1\Ebene2\Ebene3\Ebene4\' würde nun die 1. Zuweisung im 4. Aufruf fehlen erhälst du immer: '' Ich hoffe ich habe dir die Gedankengänge die zu dieser Zuweisung geführt haben etwas verdeutlichen können :coder2: |
Re: suche Funktion FindLastDir
Leider funktioniert die Funktion :mrgreen: nicht immer. Du willst doch den Pfad des am tiefsten verschachtelten Verzeichnisses haben, oder? Also benötigst Du eine Maximierung der Verschachtelungstiefen. Die fehlt hier.
Weiterhin verstehe ich nicht, wieso Du im FindFirst nur nach 'faDirectory' suchst, und dann trotzdem fragst, ob die gefundene Datei auch wirklich ein faDirectory ist... Also ich würde das weglassen. Das Break nach dem rekursiven Aufruf wird dann auch überflüssig, weil wir doch ALLE Verzeichnisse durchsuchen müssen, und nicht nur das 'erste'. Hier meine ungetestete Variante:
Delphi-Quellcode:
function FindLastDir(sDirectory : string) : string;
Var sDeepestPath : String; iMaxLevel : Integer; Procedure _DoFindLastDir (sDirectory : String; aLevel : Integer); var SearchRec : TSearchRec; begin sDirectory := IncludeTrailingPathDelimiter(sDirectory); If aLevel > iMaxLevel Then Begin // <-- wenn besuchte Tiefe > bisherige maximale Tiefe... iMaxLevel := aLevel; // <-- Dann merken wir uns diese Tiefe sDeepestPath := sDirectory; // <-- Sowie den Pfad, der uns bis hierhin gebracht hat End; if FindFirst(sDirectory + '*.*', faDirectory, SearchRec) = 0 then begin try repeat if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then _DoFindLastDir(sDirectory + SearchRec.Name, aLevel + 1); until FindNext(SearchRec) <> 0; finally FindClose(SearchRec); end; end; end; Begin iMaxLevel := -1; sDeepestPath := ''; _DoFindLastDir (sDirectory, 0); End; |
Re: suche Funktion FindLastDir
Moin,
vielleicht habe ich nicht aufmerksam genug gelesen, aber wenn ich die etwas abstrakten Anforderungen mal ignoriere und die durchscheinende Anwendungsidee betrachte, dann verstehe ich folgendes: Anders als übliche Player will der thread owner ein automatisches Abspielen von Audio-Dateien nicht über einen vom Benutzer geordneten SnapShot eines Verzeichnisbaumes steuern, sondern die physische Abfolge von Titeln unabhängig von der Tiefe der Verzeichnisstruktur heranziehen.
Code:
Nach dem Track "The Happy Whistler" soll der Track "Lyin' Eyes" gespielt werden - also ein Depth-First TreeWalk durch einen Verzeichnisbaum, bei dem die leafs die zu spielenden Tracks darstellen.
- Audio
- Best Of The 50's - Dean Martin - Memories Are Made Of This - Don Robertson - The Happy Whistler - Eagles - One Of These Nights - Lyin' Eyes - Take It To The Limit - Desperado - Tequila Sunrise Freundliche Grüße |
Re: suche Funktion FindLastDir
Zitat:
Hallo, also ganz so abstrakt sind die Anforderungen ja nicht. Grundsätzlich verwende ich das EasyListView zum darstellen der Struktur und man kann selbst durch alle Ordner zappen und irgendwas anspielen. Befinde ich mich in einem Ordner, spiele ich jetzt diesen ab und am Ende wieder zum ersten Track. Jetzt kam die Frage bei den Usern auf, ob man nicht am Ende zum nächsten Ordner springen kann und diesen dann abspielen. Das fällt bei mir so in die Art eines CD-Wechslers mit dem Unterschied, das es halt im Verzeichnisbaum auch Tiefen gibt. Mit weiteren Gedanken kam ich dann dazu, das in jedem Ordner sowie UnterOrdner als auch RestFiles liegen können, die auch automatisiert abgespielt werden müssen. Um überhaupt das Ganze zu ermöglichen, kann ich 2 Dinge tun: 1: innerhalb des ListViews gezielt die Indexe abfragen und springen, was aber immer eine Aktualisierung des Listviews zur Folge hat, also schlecht (ListView wird über FindAllFiles gefüllt) 2: Die Struktur absuchen mit Funktionen zur Pfadermittlung aber auch Funktionen für die Inhalte der wie Ordner und Files zu haben....und wenn alles richtig läuft, das PlayFile erreicht eine einmalige Aktualisierung des ListView So mal ganz unprofessionell angefangen (unfertig):
Delphi-Quellcode:
procedure FindDir;
var i:integer; aPath:string; label DirSearch; begin aPath := ExcludeTrailingPathDelimiter(PlayPath);//PlayPath merken ggf noch ändern Path := GetAudioplayerDirectory(PlayPath); //Path eine Ebene höher als PlayPath showmessage(path); DirSearch: DirLst.Clear; ListeDir(Path,DirLst); //dort alle Ordner in Stringliste holen {****nächsten Ordner unter PlayOrdner suchen und 1.Fileabspielen**************} if DirLst.Count >0 then //wenn mehr als 0 Ordner vorhanden begin for I := 0 to DirLst.Count-1 do //Ordner zählen und Play-Ordnernamen if aPath = DirLst.Strings[I] then //mit Liste vergleichen bzw suchen break; //wenn gefunden Inc(I); //Index-Nr ab Playordner um 1 erhöhen end; if (I < DirLst.Count) then //** wenn OrdnerIndex < DirLsteintraege begin if DirectoryExists(DirLst.Strings[I]) then //wenn Ordner vorhanden Path := FindLastDir(DirLst.Strings[I]); //neuen Path setzen auf tiefsten Ordner DirLst.Clear; //vom indexierten Ordner setzen FileLst.Clear; search:=true; FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true);//dort alle Ordner... search:=false; // ...und Files in Stringlisten holen,DirLst sollte //...leer bleiben da in tiefsten Ordner if FileLst.Count >0 then //wenn in Fileliste mehr als 0 Einträge begin if FileExists(FileLst.Strings[0]) then //wenn File vorhanden (1. File) begin ShowMediaFiles(listmedia,false,true); //AudioListe aktualisieren showmessage('Play in tiefster Ebene'); Play(Path,0); //dann 1.File abspielen end; end else //wenn keine Einträge in Stringliste, dann begin showmessage('kein File vorhanden in tiefster Ebene'); Goto DirSearch; end; end else if FileLst.Count >0 then //wenn erhöhter OrdnerIndex >DirLsteinträge begin //sprich kein weiterer Ordner mehr if FileExists(FileLst.Strings[0]) then //dann wenn File vorhanden (1. File) begin ShowMediaFiles(listmedia,false,true); //Audioliste aktualisieren showmessage('Play restliche Files unter Ordner'); Play(Path,0); //und 1.File abspielen end else begin //wenn Ordner und Files nicht mehr vorhanden showmessage('Loop zum ersten Ordner vom Root') fehlt noch //dann bei erstem Ordner ab MediaRoot anfangen end; |
Re: suche Funktion FindLastDir
Zitat:
Fürs abspielen der Tracks brauche ich immer den ersten Ordner im Verzeichnis in der Tiefe. Den abgespielt, wird der nächste herangezogen, keiner mehr da, dann eine Ebene höher den nachfolgenden Ordner suchen, in die Tiefe gehen.... Die Funktion sollte nur einen Teil des Ganzen sein...damit kann man nicht alle Vorgänge abfangen, wollte das in TeilFunktionen machen und dann zusammensetzen.... |
Re: suche Funktion FindLastDir
Soo hier mal die komplette Procedure um den nächsten Track zu finden und abzuspielen:
Vielleicht gibt es ja noch Verbesserungsvorschläge in Bezug auf ein Limit nach oben setzen bzw Abbrechen, wenn er zulange sucht...
Delphi-Quellcode:
procedure PlayAbsoluteNext;
var I:integer; bPath:string; label setIndex,proofFolder,proofFiles,noFiles,areFiles; begin ListFlag := True; //PlayIcons ausblenden bPath := ExcludeTrailingPathDelimiter(PlayPath);//PlayPath merken GetAudioplayerDirectory(PlayPath); //Drives abfragen if (bPath = MediaPath)or(DriveLst.Count >0) then //oberste Rootgrenze erreicht begin Path := MediaPath; I := 0; search:=true; DriveLst.Clear; DirLst.Clear; FileLst.Clear; FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true); (DirLst as TStringList).Sort; //alphab. sortieren (FileLst as TStringList).Sort; goto proofFolder; //Path eine Ebene höher als PlayPath,Rootgrenze nicht end else Path := GetAudioplayerDirectory(PlayPath); //...erreicht setIndex: //...Durchlaufpruefungen ! search:=true; DriveLst.Clear; DirLst.Clear; FileLst.Clear; FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true); (DirLst as TStringList).Sort; //alphab. sortieren (FileLst as TStringList).Sort; if DirLst.Count >0 then begin for I := 0 to DirLst.Count-1 do //Ordner zählen und Play-Ordnernamen if bPath = DirLst.Strings[I] then //mit Liste vergleichen bzw suchen break; //wenn gefunden Inc(I); //Index-Nr ab Playordner um 1 erhöhen end; proofFolder: //...auf Ordner pruefen if (I < DirLst.Count) then begin if DirectoryExists(DirLst.Strings[I]) then Path := FindLastDir(DirLst.Strings[I]);//neuen Path setzen auf tiefsten Ordner DriveLst.Clear; DirLst.Clear; FileLst.Clear; search:=true; FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true);//Inhalte holen (DirLst as TStringList).Sort; //alphab. sortieren (FileLst as TStringList).Sort; end; goto proofFiles; proofFiles: //..auf Files pruefen if FileLst.Count = 0 then goto noFiles else if FileLst.Count > 0 then goto areFiles; areFiles: //..Files vorhanden if FileExists(FileLst.Strings[0]) then begin ShowMediaFiles(listmedia,false,true); Play(Path,0); end; exit; noFiles: //..keine Files vorhanden bPath := ExcludeTrailingPathDelimiter(Path); if bPath = MediaPath then Path := MediaPath //oberste Rootgrenze erreicht else Path := GetAudioplayerDirectory(Path); //Path eine Ebene höher als PlayPath goto setIndex; //..dann erneuter Durchlauf end; |
Re: suche Funktion FindLastDir
Oh mann, das muss einem grenzdebilen Frührenter wie mir doch gesagt werden, was überhaupt gewollt ist... :oops:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:03 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