Progressbar während der Dateisuche

  • VB.NET

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von Marsianer.

    Progressbar während der Dateisuche

    Bezug: [VB 2010] Rekursive Dateisuche mit anonymer Methode?

    Hi,

    danke für die Funktion, ist genau das, was ich gesucht habe :thumbup: .
    Eine Frage noch dazu: So eine Suche kann ja ganz schön lange dauern (ggf. die ganze Festplatte abgrasen). Ich hab deshalb vor, eine Progressbar einzubauen. Nun stellt sich aber die Frage, was man da als Max-Wert einstellt. Eigentlich bietet sich dafür die Anzahl aller Dateien im System an, aber woher nehmen. Ich hab bei msdn die My.Computer.FileSystem.GetFiles gefunden, aber das scheint mir net das Richtige zu sein, weil man da wieder in die Falle mit der UnauthorizedAccessException laufen dürfte.

    Kannst du mir sagen, was man da machen kann?
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D

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

    ich weiß da nix gutes. Grad eine umfangreiche Suche ist nicht abschätzbar, wie umfangreich sie werden wird.
    Der Versuch, es abzuschätzen dauert ungefähr so lange wie die Suche selbst.
    Also kann man auch kein MaxValue bestimmen.

    Muss man halt iwelche anneren IsBusy-Anzeigen bringen, etwa PB im Marquee-Style oderwas.
    Je nun, dann muss der User sich halt in Geduld wappnen :D

    Auf jeden Fall ist deine Funktion richtig spaßig. Mit rekursiven Funktionen habe ich immer so meine Logik-Probleme, aber immerhin hab ich es geschafft, dass die Funktion mir jetzt in sämtlichen Laufwerken (die .isReady sind) jedes Directory nach vier verschiedenen Patterns durchsucht und die gesuchten Directory-Pfade in vier Listen (ohne Doppelungen, quasi DISTINCT) zurückgibt :thumbup:
    Genau so brauchte ich es. Wartezeit hält sich übrigens erstaunlicherweise in Grenzen, obwohl mein Rechner net der Neueste ist.
    Danke! :P
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D

    Marsianer schrieb:

    Mit rekursiven Funktionen
    musst Du aufpassen, dass Du da eine saubere Abbruchbedingung hast.
    Am besten, Du steppst mal eine oder 2 Schleifen zeilenweise durch, da siehst Du, was passiert und wo es ggf. klemmt.
    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!
    Richtig. Damit kann ich meine mangelhafte Vorstellungskraft, was bei einer Rekursion wirklich abgeht, ein bisschen umgehen. Im vorliegenden Fall hatte ich allerdings den Vorteil, dass die Ursprungsfunktion vom EdR stammt (s. Threadstart):
    Bezug: [VB 2010] Rekursive Dateisuche mit anonymer Methode?
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    Rekursion ist findich eine eigene Wissenschaft. Es gibt Sprachen, die kennen ühaupt keine Schleifen - nur Rekursion (k.A., warum die das so toll finden, aber is wirklich so).
    Jdfs. mit Rekursion habichmich gelegentlich auch bisserl ausschweifender beschäftigt - und türlich auch Artikelchen zu verzapft: Bäume durchlaufen mit Rekursion
    Da ist sogar ein Rekursion->Iteration-Konverter drinne (naja - c#).
    Meine Bastelidee wäre, die Menge an verbrauchtem Speicher auszulesen und nach etwa 1000 oder so Dateien die Durchschnittsgröße ausrechnen und dann diese durch den verbrauchten Speicher zu rechnen. Und so kommt du annäherungsweise auf die MaxValue, du kannst das ja dann jedesmal neu berechnen wenn du wieder 1000 Dateien eingelesen hast.


    mfg Ebrithil
    Mein Erstes Tutorial: Erweitertes Arduino Tutorial

    Simpler D&D FTP Uploader: Edge-Load

    ebrithil schrieb:

    die Menge an verbrauchtem Speicher auszulesen
    Über Festplattenparameter (Größe, Belegung usw.) hatte ich in diesem Zusammenhang auch schon meditiert, allerdings ohne daraus auf einen konkreten Ansatz zu kommen. Deine Idee finde ich cool, mal sehen, ob ich was Sinnvolles zusammenbekomme.... ;)

    ErfinderDesRades schrieb:

    Rekursion ist findich eine eigene Wissenschaft. Es gibt Sprachen, die kennen ühaupt keine Schleifen - nur Rekursion (k.A., warum die das so toll finden, aber is wirklich so).
    Ich hab mal ein bisserl nachgegoogelt. Funktionale Programmierung Haskell, F# und so 8| .
    Für den, der Mathe kann, könnte das durchaus seinen Reiz haben, Wikipedia verweist ja darauf, dass diese Sprachen eigentlich ein anderes Ziel haben, als imperative Sprachen:

    Wikipedia schrieb:

    Ein Ansatz der funktionalen Programmierung ist, dass ihre Funktionen sich mehr wie mathematische Funktionen verhalten, damit die Rechen- und Beweismethoden der Mathematik besser auf Programme angewendet werden können (um vor allem ihre Korrektheit zu beweisen).
    Mir hilft das net weiter, Mathe war ich meistens so um die 4 rum. Erstaunlich, wie man dann trotzdem beim proggen recht weit kommt. Nein, die mathematische Schönheit einer Sprache kann für mich kein Kriterium für die Wahl meiner Entwicklungsumgebung sein. Eher ausgereifte Designer, umfangreiche Dokumentationen, gigantische Klassenbibliotheken (wobei das anfangs eher abschreckend wirkt) und Programmierparadigmen, die selbst ich (meistens) verstehe 8-) . Imperativer Beginners All-purpose Symbolic Instruction Code halt :D
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D

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

    Vielleicht formulierst Du aus jetziger Sicht Dein Problem noch mal neu.
    Ggf.ist es sinnvoll, die Root-Verzeichnisse beim Zählen zu vereinzeln.
    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!
    Okay: Es geht darum, dass ich eine rekursive Funktion habe, die alle erreichbaren Festplatten nach bestimmten Patterns abgrast. Da das eine Weile dauert, möchte ich dem User irgendwie den Fortschritt anzeigen. Ich habe an eine Progressbar gedacht, weiß aber nicht, was ich da als Max-Wert nehmen soll, da ich beim Start der Funktion keine Ahnung habe, wie lange und tief sie graben wird. Sie ist halt rekursiv.

    Ebrithil hat mich da auf eine Spur gebracht. Ich überleg im Moment folgende Logik für die Progressbar:
    Max-Wert = 100, Step 10
    Summe des belegten Platzes auf allen Festplatten ermitteln. Diesen Wert durch 10 teilen.
    In der rekursiven Funktion die Größe der durchwühlten Directorys aufsummieren.
    Immer wenn diese Summe ein Zehntel des gesamten belegten Platzes überschreitet: Mit Progressbar einen Step weiter.

    Ist das halbwegs stringend oder habe ich da was übersehen. Ansonsten werde ich mal mit Try and Error versuchen, sowas zusammen zu basteln.
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    Ja das ist die einfachste Möglichkeit, ich würde vielleicht nicht gerade 10er Steps nehmen sonder 1ner bei max 100
    Und dann hald den Speicher durch 100 und die Grösse aller gescannten Dateien zusammenrechnen und dadurch den 100% Anteil auszurechnen.

    Ist aber auch nicht ganz korrekt, da man ja für Grosse Dateien im Vergleich zur Grösser weniger Zeit/Grösse hat.

    Must vielleicht, diese und meine Beschrieben Variante verwenden un den Mittelwert berechnen, dann kommst du vielleicht auf ein relativ vernünftiges Resultat.



    mfg Ebrithil
    Mein Erstes Tutorial: Erweitertes Arduino Tutorial

    Simpler D&D FTP Uploader: Edge-Load
    Ich versuch das mal zu impementieren.

    ebrithil schrieb:

    Ist aber auch nicht ganz korrekt, da man ja für Grosse Dateien im Vergleich zur Grösser weniger Zeit/Grösse hat.
    Okay, die Progressbar wird vielleicht ein wenig sprunghaft laufen, aber das sehe ich noch nicht mal als Problem an. Mal sehen, wie sich das in der Praxis macht. Ich melde mich, wenn ich's zum Laufen gekriegt habe.
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    Funktioniert das mit dem "nach bestimmten Patterns abgrasen" schon? Wenn nein, mach es erst mal.
    Du kannst ja so lange Progress = 0 anzeigen, wie Du in einem 2. Thread die Anzehl der Dateien ermittelst. Die dann aber für jedes Root-Verzeichnis, wegen ggf. gesperrten Verzeichnissen.
    Wenn dann das Ergebnis vorliegt, kannst Du Deine Progressbar updaten.
    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!
    Das 'Abgrasen' :) funktioniert tadellos und liefert auch korrekte Ergebnisse, das habe ich schon ausgetestet. Es geht mir jetzt wirklich nur noch darum, den User während dieses Prozesses zu informieren, damit er nicht unruhig wird. Bisher läuft die ganze Funktion im Hauptthread, weil ich mich mit Threading überhaupt noch nicht beschäftigt habe. Ich hatte schon genug damit zu kämpfen, mit VB einigermaßen warm zu werden und die ganze Datenbänkerei in den Griff zu bekommen. Somit ist das Programm während der Pattern-Sucherei natürlich lahmgelegt. Das ist aber relativ unschädlich, weil ich gerade einen Assistenten zur Ersteinrichtung meiner Anwendung schreibe. Es geht darum, dass der User mehrere Verzeichnispfade angeben muss, wo das Prog dann die Daten hinschreiben soll. Die hier diskutierte Suchfunktion ist ein Angebot an den User, dass der Wizzard das System mit Hilfe der Patterns nach bereits vorhandenen Daten absucht (zB nach einer Neuinstallation), wenn der User nicht weiß, wo er seine Daten gelassen hat :) . Dafür muss er sich halt in Geduld üben. Da der Assistent mit dem nächsten Einrichtungsschritt sowieso erst weitermacht, wenn er für alle notwendigen Pfade gültige Verzeichnisse genannt bekommen hat, kann er nicht 'nebenbei' mit dem Prog weiterarbeiten. Falls das beim Helfen hilft, kann ich ja mal einen Screenshot von meiner Wizzard-Form hochladen und den Code von der Funktion dazu (geht aber erst heute Nachmittag).
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D
    Wär jetzt auch meine Idee gewesen, du lässt erstmal die Gesamtzahl der Dateien ermitteln und speicherst das dann als Integer und gibst das dann als .MaxValue an.

    DAS wird zwar mind. genauso lange wie die suche dauern aber naja, es geht ja nicht um schnelligkeit wie ich das hier gelesen habe ;)

    Marsianer schrieb:

    wenn der User nicht weiß, wo er seine Daten gelassen hat
    Dafür gibt es das Verzeichnis ProgramData\NAME_DEINES_PROGRAMMS, da würde ich dem User keine Auswahlmöglichkeit geben.
    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!

    Marsianer schrieb:

    das System mit Hilfe der Patterns nach bereits vorhandenen Daten absucht (zB nach einer Neuinstallation), wenn der User nicht weiß, wo er seine Daten gelassen hat :) .
    wäre es auch eine Alternative, eine eigene DateiEndung zu creiern, und die Anwendung damit zu verknüpfen? Dann startet der User die Anwendung gar nicht mehr direkt, sondern per Doppelklick auf seine DatenDatei.
    Das verlangt dem User natürlich den Umgang mit dem WinExplorer ab, und der wird ja auch von Windows zu Windows immer bescheuerter, und ob unter Win7 ühaupt noch vorgesehen ist, dass User wissen, dasses ein Dateisystem gibt, weiß wiederum ich nicht.

    Oder der User darf ganicht bestimmen wo gespeichert wird, sondern das Teil speichert halt im vom System bereitgestellten AppDataPath.
    (@Rod: 2 Doofe, ein Gedanke ;))

    RodFromGermany schrieb:

    Dafür gibt es das Verzeichnis ProgramData\NAME_DEINES_PROGRAMMS,

    Hmmm....ja. Ich mag dieses Verzeichnis nicht und ich gebe zu, mit den Bibliotheken und Sonderverzeichnissen von Windows habe ich mich nie groß auseinandergesetzt. Schon seit DOS-Zeiten bin ich es gewohnt für Betriebssystem/Programme und Daten unterschiedliche Festplatten zu benutzen. Meine C:\-Festplatte ist relativ klein, dafür habe ich eine Terabyte-FP, wo meine Daten liegen.
    Okay, das ist mein persönliches Ding, aber deswegen würde ich dem User durchaus die Wahl lassen, wo er die Daten hingeschrieben haben will.
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D

    ErfinderDesRades schrieb:

    @Rod: 2 Doofe, ein Gedanke ;)
    Soooooo doooooooof sin wir ja nunn auch wider nich. :D
    -----------------------------

    Marsianer schrieb:

    aber deswegen würde ich dem User durchaus die Wahl lassen, wo er die Daten hingeschrieben haben will.
    Das Laufwerk: Ja, den Ordner: Nein.
    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!

    ErfinderDesRades schrieb:

    wäre es auch eine Alternative, eine eigene DateiEndung zu creiern, und die Anwendung damit zu verknüpfen? Dann startet der User die Anwendung gar nicht mehr direkt, sondern per Doppelklick auf seine DatenDatei.
    Eigene Endung wirkt immer cool :D , aber ich glaube, das macht wenig Sinn bei mir. Die Datenbanken sind SqlCE und die haben standardmäßig .sdf-Endung. Ich weiß nicht, ob SqlServerCe meckern würde, wenn man ihm andere Endungen vorwirft. Und die Datenbank-Reports sind PDF-Dateien, da möchte ich net an die Endung ran.

    RodFromGermany schrieb:

    Das Laufwerk: Ja, den Ordner: Nein.
    Klar, das macht man ja häufig so. Aber zwingend notwendig ist das doch eigentlich nicht, oder?

    Okay, das führt ja jetzt alles vom eigentlichen Thread-Thema weg, aber hier mal Kurzübersicht über meinen Programmaufbau (damit ihr nicht im Nebel herumraten müsst):
    Grundidee: Mein persönliches Programm um meine Privatfinanzen zu verwalten (Datenbank)
    Das Programm generiert eine dateibasierte DB, wo die Daten reinkommen (die heißt MeinFinanzKnechtDB.sdf)
    Es ist möglich, von dieser 'Original-Datenbank' programmgesteuert Kopien zu erzeugen, mit denen man rumspielen kann, ohne die Originaldaten zu verändern (ermöglicht das Durchspielen von was-wäre-wenn-Szenarien: wie entwickeln sich die Finanzen, wenn ich mir ein neues Haus/Auto kaufe, neue Wohnung beziehe, neue Arbeit anfange usw.) Auch das sind natürlich .sdf-Dateien.
    Das Programm produziert (per iTextSharp.DLL) Berichte in PDF-Form. Immer am Monatsanfang wird vom vergangenen Monat ein sogenannter Schlussbericht erstellt und abgespeichert (diesen Bericht kann der User auch nicht mehr durch Änderungen an den Daten verändern, denn der vergangene Monat war halt, wie er war 8-) ).
    Das Programm erstellt auch eigenständig Backups von den Daten und bietet eine Restore-Funktion an.
    Für die Original-Datenbank, die Szenario-DB's, die Monatsberichte und die Backups sind in My.Settings jeweils Dateipfade hinterlegt. Es steht dem User frei, ob er jeweils ein anderes Verzeichnis auswählt oder für alle Dateien immer das gleiche Verzeichnis angibt.
    Bei Start des Programms wird über eine Einstellung in My.Settings geprüft, ob das der Erststart des Progs ist. Wenn ja startet der Einrichtungsassistent. Er fragt die Dateipfade ab (und bietet dabei die Suchfunktion an, wegen der ich diesen Thread gestartet habe). Weiterhin legt er, falls nötig eine neue leere Datenbank an.
    So im Groben.
    Ich code nur 'just for fun'! Damit kann ich jeden Mist entschuldigen, den mein Interpreter verdauen muss :D