Announcement

Collapse
No announcement yet.

Problem mit FindFirst, FindNext und FindClose...

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem mit FindFirst, FindNext und FindClose...

    Hi,

    Ich habe folgendes Problem, wenn bei einer FindFirst, FindNext Routine als Attribut faDirectory angeben wird, werden trotzdem alle Dateien die in dem zu durchsuchenden Verzeichnis sind mit angezeigt. Ich möchte aber nur alle Directorys / Verzeichnisse angezeigt bekommen. Und wenn als Attribut faAnyFile angezeigt wird, werden Verzeichnisse mit als Suchergebnis ausgegeben und nicht nur Dateien. ???? Was kann ich dagegen tun?? Hat jemand eine Idee?

  • #2
    Hi <br>
    das Attribut ist nicht ausreichend <br>

    If((search.attr and FaDirectory)=FaDirectory)and(search.name[1]<>'.')Then Directory <br>
    Gruß<br>
    Andrea

    Comment


    • #3
      Hallo,<br>
      <br>
      auf den Namen '.' abzutesten genügt leider nicht, es muss auch auf '..' getestet werden.<br>
      Der einzelne Punkt steht für das Verzeichnis selbst, die zwei Punkte für das übergeordnete Verzeichnis.<br>
      (selbst wenn es dieses im Root eines Laufwerkes nicht gibt)<br>
      Das lässt sich in Dos gut ausprobieren z.b. mit Dir .<br>
      das entspricht dir *.*<br>
      (Vorsicht: gilt natürlich auch für del!)<br>
      <br>
      Ciao<br>
      Chri

      Comment


      • #4
        Klar reicht das, Christian. In ".." ist doch der erste Punkt auch drin, die Bedingung
        <pre>if ...(search.name<font color=#ff0000>[1]</font> <> '.')</pre>
        (wenn das erste Zeichen von search.name kein Punkt ist)genügt vollkommen.<br><br>
        Mathias

        Comment


        • #5
          NEIN, genügt eben nicht, da bei dieser Abfrage alle regulären Ordner die mit '.' beginnen ebenfalls unterdrückt werden. Unter DOS kein Problem da es solche Ordnernamen NICHT geben darf, unter neueren System aber sehr wohl möglich. Heist also die Abfrage

          <pre>

          if (SR.Attr and faDirectory <> 0) and<br>
          (SR.Name <> '.') and<br>
          (SR.Name <> '..') then .....

          </pre>

          IST richtig.

          Gruß Hage

          Comment


          • #6
            Das ist mir neu. Ich kann <u>keinen</u> Ordner anlegen, der mit einem Punkt beginnt. Und ich hab´s gerade unter Win98 und 2000 probiert, sogar unter XP - und das sind neuere Systeme. Das ist ebenso als würde ich eine Datei namens ".htaccess" anlegen wollen. Das mag unter Linux gehen, aber nicht unter Windows. Besser gesagt: nicht unter <b>meinen</b> Windows-Versionen, die ich hier benutze. Sagt mir wenn ich mich irre.

            Oder muss ich etwa noch irgendwo etwas einstellen, damit das klappt?

            Mathias

            Comment


            • #7
              Siehste, nächster Irrtum. Du kannst keinen solchen Ordner anlegen, ich dagegen habe eine Software die direkt die FAT manipuliert, und somit jeden beliebigen namen nutzen kann. Das ist ein steinalter DOS Trick um Directory unlöschbar, unsichtbar zu machen oder einfach als normale datei zu tarnen. (ein ordner kann auch eine Extension besitzen!) Das funktioniert aber auch nur weil die meisten Programme in ihrem code die irrige Annahme manchen das mit der abfrage des ersten Chars auf '.' alles erledigt wäre Die beiden EINZIGSTEN Ordner die in einer rekursiven Routine ausgelassen werden müssen sind die Ordner '.' und '..' und NUR exakt diese !! Heist also genau diese wollen wir abfragen und es gilt die Ungleichung:<br>

              (Name = '.' or Name = '..') <> (Name[1] <> '.')<br>
              <br>
              Gruß Hage

              Comment


              • #8
                Hallo Zusammen,<br>
                <br>
                um ein Verzeichnis anzulegen, dass mit einem Punkt beginnt, ist nicht einmal spezielle Software vonnöten.<br>
                Das geht schlicht in der Dos-Box.<br>
                Das Gleiche gilt auch für Dateien.<br>
                MD .TEST oder COPY CON: .TEST funktionieren auch unter W2K.<br>
                Es können auch mehrere Punkte am Anfang stehen.<br>
                Da ich mal vermute, dass viele COPY CON: nicht kennen: Damit wird die Konsoleneingabe (Tastatur), die man folgen lässt<br>
                in die Datei, die als zweiter Paramter steht, kopiert.<br>
                Beendet wird die Eingabe mit F6, was gleichbedeutend ist mit STRG-Z, dem Dateiende Kennzeichen, und anschliessendem STRG-M (Return).<br>
                Innerhalb der Eingabe kann Return für den Zeilenvorschub verwendet werden.<br>
                Das ist also wohl die minimalste Möglichkeit unter Dos eine Textdatei zu schreiben, wenn auch nicht richtig zu editieren.<br>
                Für den Notfall ganz brauchbar, um z.B. eine Config.Sys oder Autoexec.bat zu erzeugen, ohne Editor.<br>
                <br>
                Ciao<br>
                Chri

                Comment


                • #9
                  @Hagen: Sorry, aber du kannst nicht als Argument bringen, dass <b>du</b> eine Software hast, die die FAT direkt manipuliert. Die habe ich nicht, und wahrscheinlich werden auch die wenigsten hier diese Software haben. Das erinnert mich an selbst geschriebene alte TurboPASCAL-Programme, mit denen man auch dafür sorgen konnte, dass diverse Sonderzeichen in Datei- und Verzeichnisnamen auftauchten, was DOS an sich nie zugelassen hätte.

                  Da überzeugt mich Christian schon eher, und ich muss zugeben, das nicht gewusst zu haben. Aber wenn man sich in der DOS-Box mal den Verzeichnisnamen anguckt, dann steht da zwar ".test" für den langen Dateinamen aber nach wie vor "test~1" für den kurzen 8.3-Namen.

                  Mathias

                  Comment


                  • #10
                    Hi Matthias

                    Du verstehst mich falsch. mein Argument IST NICHT diese Software, main argument ist das die Aufgabenstellung und die Notwendigkeiten zwei bestimmte Ordner rauszufiltern, ganz klar den zu programmierenden Algotihmus VORGEBEN.

                    Heist wenn die beiden Ordner '.' und '..' das, UND NUR DIESE BEIDEN, rausgefilteret werden müssen, dann muß die Abfrage:<br>

                    if (SR.Name <> '.') and (SR.Name <> '..') ... then ; <br>

                    lauten, und NICHT anders. Jede andersartige Überprüfung würde nicht mehr dem geforderten Ziel entsprechen und daher versagen. Die Annahme irgend einer anderen Vermutung IST also IMMER falsch. Tatsachen zählen, und Tatsache ist das Ordner und datei sehr wohl am Anfang ihres Namens ein '.' oder '..' oder '...' oder '....' .... haben dürfen. Mein Hinweis auf diese spezielle Software IST nur eine konsequenz.

                    Gruß Hage

                    Comment


                    • #11
                      Überzeugt mich immer noch nicht, Hagen. )
                      Wenn´s eine Tatsache wäre, dann gäbe es die Möglichkeit auch in der Windows-Oberfläche und nicht nur in der DOS-Box. (Um bei Christians Beispiel zu bleiben.) Schließlich legt der Befehl "md .Test" ja, wie gesagt, einen kurzen Dateinamen an, der den Windows-Konventionen entspricht. Und die Anzeige im Explorer ist kein Problem. Warum also geht´s nicht gleich dort?

                      Ich tippe mal, dass dies einer der berühmten MS-Bugs ist, bzw. dass Microsoft vergessen hat, diese Fähigkeit entsprechend auszudehnen. Im letzteren Fall hättest du natürlich recht, weil es eine gewollte Sache des Systems ist. Im ersteren Fall habe ich recht, weil´s eben nicht gewollt ist -- dann gibt´s nämlich nur . und .., und ein Punkt hat am Anfang eines Ordners nichts zu suchen. Deswegen ja auch der "Vorwurf", dass man mich nicht mit Spezialprogrammen, die solche Sachen umgehen, überzeugen kann. )

                      Ich weiß nicht mehr, wer es war und wo. Kann sein, dass du es sogar warst, Hagen, der sagte (mal frei aus´m Kopf "Auch wenn Lücken im System da sind, sollte man nicht spekulieren, dass dies überall so ist, und schon gar nicht sollte man solche Lücken ausnutzen."

                      Bleibt also die Spekulation, was Microsoft nun wollte.
                      Ich hab´ keine Ahnung. |

                      Mathias

                      Comment


                      • #12
                        Hi

                        Ja, ich war das. Und genau dies trifft ja auch hier zu, eben umgekehrt. Deine Abfrage Name[1] <> '.' IST also FALSCH, da es nicht existente Regeln des Betriebssystems vorraussetzt.<br>

                        anderes Beispiel: <br>
                        Q: "Programiere eine Funktion die überprüft ob ein String NICHT "Test" heist !"<br>

                        <pre>

                        A1: <br>
                        Result := String[1] <> 'T'; <br>

                        A2: <br>
                        Result := String <> 'Test';<br>

                        </pre>

                        A1 ist definitiv die falsche Antwort, A2 ist definitiv richtig.<br>

                        Nun die Frage 2: "Überprüfe ob ein String nicht '.' und nicht '..' ist!"<br>

                        Antwort weisste ja selber.

                        Gruß Hage

                        Comment


                        • #13
                          Achso: <b>md %Name</b> solltest Du mal im DOS Handbuch nachlesen.
                          <b>md</b> = <i>Make Directory</i><br>
                          Gehe in die MS-DOS Box und gebe ein "md .test", danach zurück in den Explorer und ansicht aufgefrischt. Als Resultat siehst Du einen neuen Ordner der ".Test" heist. Ob nun das Windows-GUI einen solchen Namen in der Editbox zulässt oder nicht IST egal, da das darunterliegenden Dateisystem es eben ERLAUBT und UNTERSTÜTZT !! D.h. vom OS her ist es sehr wohl erlaubt Ordner und dateien mit führendem Punkten zu benamen.

                          Gruß Hage

                          Comment


                          • #14
                            Und ich war mir so sicher ... &lt;grummel&gt; ... So, aber erst mal die Antwort zu Frage 2:<br><br>
                            <pre>Result := (String[2] <> '.') and (length(String) > 2);</pre>
                            Ätsch! :-D<br><br>
                            Mathias

                            Comment


                            • #15
                              Ok, es reicht. Nehme ein neues Form, knall ein TMemo und ein TButton drauf. Nun gehste auf Laufwerk D: in die DOS BOX und gibts nacheinander ein:<br>

                              D:\<br>
                              MD TEST<br>
                              CD TEST<br>
                              MD .TEST<br>
                              MD .T<br>
                              MD ..TEST<br>
                              MD T.<br>
                              MD T.T<br>
                              <br>

                              Nun folgenden Code:

                              <pre>

                              procedure Scan(const Path: String; List: TStrings);
                              var
                              SR: TSearchRec;
                              S: String;
                              begin
                              if FindFirst(Path + '*.*', faAnyFile, SR) = 0 then
                              repeat
                              if SR.Attr and faDirectory <> 0 then
                              begin
                              S := '---';
                              if (SR.Name[1] <> '.') then S[1] := '1';
                              if (SR.Name[2] <> '.') and (Length(SR.name) > 2) then S[2] := '2';
                              if (SR.Name <> '.') and (SR.Name <> '..') then S[3] := '3';
                              List.Add(SR.Name + ', ' + S);
                              end;
                              until FindNext(SR) <> 0;
                              FindClose(SR);
                              end;

                              </pre>

                              und mit Scan('D:\Test\', Memo1.Lines); aufrufen.<br>

                              in den Lines sollte dann folgendes stehen:

                              <pre>

                              . , ---
                              .. , ---
                              .test , -23
                              .t , --3
                              ..test , --3
                              t , 1-3
                              t.t , 1-3

                              </pre>

                              Alle 3 methoden filtern '.' und '..' aus, das zeigen die '---' an.
                              NUR Methode 3, <b> also MEINE </b> filtern in JEDEM Fall korrekt.
                              Auch Deine Method 2 versagt im Falle von 't.' und 't.t' Ordnern.

                              Wie gesagt probiers, und streit Dich nicht mit mir wenn Du nicht genau überlegt hast was Du sagst.<bR>

                              Gruß Hage

                              Comment

                              Working...
                              X