IO.GetDirectories nur Ordner auflisten, die MP3 Dateien enthalten.

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 32 Antworten in diesem Thema. Der letzte Beitrag () ist von MichaHo.

    @Gonger96 das funktioniert auch, dauert aber gefühlt länger:

    C#-Quellcode

    1. public static List<DirectoryItem> GetFilesFolders(this string path)
    2. {
    3. var items = new List<DirectoryItem>();
    4. if (!Directory.Exists(path)) return new List<DirectoryItem>();
    5. var folders = new DirectoryInfo(path).EnumerateDirectories();
    6. List<FileInfo> files = new DirectoryInfo(path).GetMP3Files();
    7. Parallel.ForEach(folders, (folder) =>
    8. {
    9. if (folder.HasMP3Files())
    10. items.Add(new DirectoryItem { FullPath = folder.FullName, Type = DirectoryItemTypeEnum.Folder });
    11. });
    12. if (files.Count > 0)
    13. {
    14. items.AddRange(files.Select(f => new DirectoryItem { FullPath = f.FullName, Type = DirectoryItemTypeEnum.File }));
    15. }
    16. return items;
    17. }
    18. #endregion
    19. public static bool HasMP3Files(this DirectoryInfo dirInfo)
    20. {
    21. try
    22. {
    23. return dirInfo.EnumerateFiles("*.mp3", SearchOption.AllDirectories).Any();
    24. }
    25. catch (UnauthorizedAccessException)
    26. {
    27. return false;
    28. }
    29. }
    30. public static List<FileInfo> GetMP3Files(this DirectoryInfo dirInfo)
    31. {
    32. if (!dirInfo.Exists)
    33. throw new DirectoryNotFoundException();
    34. try
    35. {
    36. return dirInfo.EnumerateFiles("*.mp3").ToList();
    37. }
    38. catch (Exception)
    39. {
    40. return null;
    41. }
    42. }
    "Hier könnte Ihre Werbung stehen..."
    OK, hab ich geändert, bringt leider nichts...

    C#-Quellcode

    1. foreach (var folder in new DirectoryInfo(path).EnumerateDirectories())
    2. {
    3. if (folder.HasMP3Files())
    4. items.Add(new DirectoryItem { FullPath = folder.FullName, Type = DirectoryItemTypeEnum.Folder });
    5. }


    oder

    C#-Quellcode

    1. Parallel.ForEach(new DirectoryInfo(path).EnumerateDirectories(), (folder) =>
    2. {
    3. if (folder.HasMP3Files())
    4. items.Add(new DirectoryItem { FullPath = folder.FullName, Type = DirectoryItemTypeEnum.Folder });
    5. });

    ist beides genauso lange wie vorher...
    ich vermute immernoch, es liegt an der SearchOption.AllDirectories.
    "Hier könnte Ihre Werbung stehen..."
    @MichaHo Ich bin mit dem Parallel.ForEach() nicht ganz glücklich, denn möglicherweise ist var items = new List<DirectoryItem>(); nicht Thread-Save und da wirst Du ausgebremst.
    Probierma, für jeden Thread eine eigene List<> zu generieen, die Du dann hinterher zusammensetzt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany ich hatte es ja auch mit einer normalen Foreach versucht und den Hinweisen von @Gonger96.
    Weis auch nicht ob ich Dich richtig verstanden habe:

    C#-Quellcode

    1. public static List<DirectoryItem> GetFilesFolders(this string path)
    2. {
    3. var itemsAll = new List<DirectoryItem>();
    4. List<DirectoryItem> folders;
    5. if (!Directory.Exists(path)) return new List<DirectoryItem>();
    6. List<FileInfo> files = new DirectoryInfo(path).GetMP3Files();
    7. Parallel.ForEach(new DirectoryInfo(path).EnumerateDirectories(), (folder) =>
    8. {
    9. folders = new List<DirectoryItem>();
    10. if (folder.HasMP3Files())
    11. folders.Add(new DirectoryItem { FullPath = folder.FullName, Type = DirectoryItemTypeEnum.Folder });
    12. itemsAll.AddRange(folders.Select(f => new DirectoryItem { FullPath = f.FullPath, Type = DirectoryItemTypeEnum.Folder }));
    13. });
    14. if (files.Count > 0)
    15. {
    16. itemsAll.AddRange(files.Select(f => new DirectoryItem { FullPath = f.FullName, Type = DirectoryItemTypeEnum.File }));
    17. }
    18. return itemsAll;
    19. }

    dauert genauso lange...
    "Hier könnte Ihre Werbung stehen..."
    ich glaub nicht, dass man mit iwelchen Threading-Tricks Zeit rausschinden kann.
    Datei-Suche ist ein Orgeln auf der Platte, und die lässt sich nicht in mehrere aufteilen.

    Es gibt immerhin Betriebssystem-nähere Befehle, die ca. 4 mal schneller sind als System.IO - Krams.
    Aber vom Prinzip her wüsste ich auch nix anneres:
    Alles durchgucken und das unerwünschte wegwerfen.
    in dem Zusammenhang ist dann Paralle.ForEach tatsächlich am schnellsten.
    Den UserOrdner schafft der Code in 11 Sekunden.
    Muss ich halt was anzeigen das man sieht das was passiert, oder doch den OpenFileDialog nutzen...
    Der passt halt vom Design her absolut nicht zum Programm...
    Vielleicht mach ich aber eher auch so das ich das folder einfach darauf prüfe ob ich Rechte hab das zu öffnen oder nicht, und blende noch alle aus die Perse versteckt sind. Dann erreiche ich ja auch fast das was ich wollte...
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    Muss ich halt was anzeigen das man sieht das was passiert
    Lrgst Du halt einen SplashScreen drüber mit ner Marquee-ProgressBar.
    @ErfinderDesRades Das wäre ne Untersuchzng wert, denn es wird ja nur Header-Infos gelesen, nicht aber riesige Dateien.
    Und die hat das System ab dem zweiten Aufruf glaub ich im Cache, da könnten sie also schon sein, und da macht Parallel schon Sinn, erst Recht mit den näheren Befehlen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi,
    da hab ich gestern noch dran gebastelt, wird aber eher ein Border mit halbdurchsichtigem Hintergrund und nem drehenden Icon. Ist ja WPF, da geht das ganz schön.
    Eine andere Idee wäre noch, vorher die Fokder schon raus zu sortieren, wo eh keine Berechtigung besteht oder die versteckt sind. Das sollte ja dann nochmal paar millisekunden bringen. Teste ich heute aus.
    Danke Euch allen, bleibt gesund...
    "Hier könnte Ihre Werbung stehen..."
    uff uff - jetzt "mein Code" doch noch gefunden - ist garnet meiner, sondern ist im Kern von SimpleSoft.
    Aber ist dieselbe Technik wie die aussem CodeProjekt-Artikel
    Rekursive Dateisuche in .Net 4.5
    und folgende

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()