[Java] Rekursion

Naja ich werde jedenfalls weiterhin die normale Instanzierungsmethode verwenden ;)


contains stimmt aber du rufst diese auf dem falschen Objekt auf bzw. übergibst das falsche Objekt. Wenn du contains auf der Liste aufrufst, suchst diese nach dem Vorkommen eines Dateinamens, den du übergibst. Dieser ist natürlich nicht darin enthalten. Du kannst also entweder über die Liste iterieren und contains(filename) auf jedem Element aufrufen oder du rufst auf der Liste contains(dateiendung) auf. Edit: endsWith() wäre in diesem Fall die bessere Wahl.

Wieso, das passt doch dann so wie ich es gelöst habe ( bist auf das, das es net geht).
In jedem beispiel welches ich gefunden habe steht:
liste.contains(zuSuchendesWort)
und das mache ich doch.
Ich übergebe der Methode eine Liste von zu überprüfenden Wörtern und das File selbst, und dann wird halt geschaut ob der Name des Files oder ein Teil davon in der Liste vorhanden ist und dann gibts true/false zurück.
Wenns true ist, wird er dann halt in mein dataList geschrieben.
endsWith() wäre nicht die beste Lösung.
Die Methode isWantedFile() schaut ob der mime-type vorhanden ist.
Bei searchByName will ich nach einem Namen suchen, mkv usw hab ich jetzt nur aus gemütlichkeit gewählt.


Afaik kann listFiles auch mal null zurück liefern, dass musst du abfangen. Dabei handelt es sich entweder um eine Datei oder du hast keine Rechte den Ordnerinhalt anzuzeigen.

Wegen letzterem solltest du auch canRead() nicht benutzten, da dies auch mal false liefern kann, obwohl der Ordner lesbar ist. Wenn man es ganz richtig machen will, solltest du auch exists() hier nicht nutzen, Stichwort "Race Condition". try-catch ist dir bekannt?

Okey, das ich hier kein exists() benötige sehe ich ein.
Das Problem ist, wenn ich canRead() nicht verwende schmeist er mir sofort ne Fehlermeldung.
Wie kann ich das umgehen das ich locked ordner lesen kann, die lesbar sind?
Sprich, in C:\\ sind ein paar ordner mit nem Schloss gezeichnet, ein paar davon kann ich anschaun, andere wiederrum nicht. Wie kann ich Java sagen, dass ich die lesen kann?

Sowas: ?
PHP:
try
{
   if (fileList[i].canRead()) {
                if (fileList[i].isDirectory()) {
                    System.out.println(repeat(" ", level * 2) + fileList[i]);
                    File f2 = new File(fileList[i].getPath());
                    build(f2.toString(), level);
                } else {
                    if (fileList[i].isFile()) {
                        System.out.println(repeat(" ", level * 2) + fileList[i]);
                        if (isWantedFile(fileList[i], mimeTypeList())) {
                            dataList.add(fileList[i]);
                        }
                        //  if (searchByName(fileList[i], nameSearchList())) {
                        //    dataList.add(fileList[i]);
                        // }
                    }
                }
            }
}
catch(NullPointerException ex)
{
 continoue;
}
Sodass er danach wieder in der Schleife weitergeht, oder wie meinst?
 
Schattenfänger schrieb:
Ich übergebe der Methode eine Liste von zu überprüfenden Wörtern und das File selbst, und dann wird halt geschaut ob der Name des Files oder ein Teil davon in der Liste vorhanden ist und dann gibts true/false zurück.
Der fett markierte Teil ist falsch.

Schattenfänger schrieb:
Das Problem ist, wenn ich canRead() nicht verwende schmeist er mir sofort ne Fehlermeldung.
Wäre super, wenn du die Fehlermeldung auch posten würdest. Ich glaube nähmlich nicht, dass canRead() eine Exception wirft sondern der Zugriff auf ein null-Objekt.

Schattenfänger schrieb:
Wie kann ich das umgehen das ich locked ordner lesen kann, die lesbar sind?
1. Nicht canRead() benutzen.
2. Deinem Programm die nötigen Rechte zum lesen besorgen. Wenn du das Programm als Admin startest, solltest du wichtigsten Ordner lesen können.

Schattenfänger schrieb:
continoue?
Das ist 1. falsch geschrieben und 2. überflüssig, da du ja schon am Ende des Schleifen-Blocks bist.

Kannst du so machen oder eben mit fileList == null prüfen. Du musst aber noch evtl. auftretende IOExeptions abfangen.
Die Prüfung, isFile() kannst du streichen, da du ja schon auf isDirectory() geprüft hast.

Edit: Nein, kannst du nicht ganz so machen. Im Schleifen-Kopf greifst du ja schon auf fileList, das auch null sein kann, zu und bekommst eine Exception um die Ohren gehauen. Da muss definitiv das fileList == null hin.
 
Zuletzt bearbeitet:
Der fett markierte Teil ist falsch.

hmm dabei hatte ich in einem früheren Post gefragt ob es so funktioniert....
Naja habe es jetzt mit regex gelöst, obwohl das bei PHP einfach gelöst ist....

1. Nicht canRead() benutzen.
2. Deinem Programm die nötigen Rechte zum lesen besorgen. Wenn du das Programm als Admin startest, solltest du wichtigsten Ordner lesen können.

Machs jetzt so:
PHP:
 public void build(String path, int level) {
        level++;
        dir = new File(path);

        File[] fileList = dir.listFiles();

        for (int i = 0; i < fileList.length; i++) {
            try {
                if (fileList[i].isDirectory()) {
                    System.out.println(repeat(" ", level * 2) + fileList[i]);
                    File f2 = new File(fileList[i].getPath());
                    build(f2.toString(), level);
                } else {
                    if (fileList[i].isFile()) {
                        System.out.println(repeat(" ", level * 2) + fileList[i]);
                        //  if (isWantedFile(fileList[i], mimeTypeList())) {
                        //     dataList.add(fileList[i]);
                        // }

                        if (searchByName(fileList[i], nameSearchList(this.gui.namesToSearch()))) {
                            dataList.add(fileList[i]);
                        }
                    }
                }
            } catch (NullPointerException ex) {
                // JOptionPane.showMessageDialog(null, "nullpointer ");
            }
        }
    }
Aber das ich Zugriff zu allen habe dürfte doch sowieso nicht gehn, da ich das ja nichtmal manuel habe, und mich erst mühsam durchklicken muss um rein zu kommen.

Hmm jetzt muss ich noch rausfinden wie man bei ner textarea einen Zeilenumbruch macht..... :mad:
 
Schattenfänger schrieb:
hmm dabei hatte ich in einem früheren Post gefragt ob es so funktioniert....
Naja habe es jetzt mit regex gelöst, obwohl das bei PHP einfach gelöst ist....
Sofern fileList Dateinamen enthält hast du natürlich recht. Ich war davon ausgegangen, dass dort lediglich die Dateiendungen gelistet sind, von denen du gesprochen hast.

Schattenfänger schrieb:
Aber das ich Zugriff zu allen habe dürfte doch sowieso nicht gehn, da ich das ja nichtmal manuel habe, und mich erst mühsam durchklicken muss um rein zu kommen.
Windows verweigert eben gerne Zugriffe auf Systemkritische Ordner. Da dürften sich aber wohl kaum avi's drin befinden. ;)

Schattenfänger schrieb:
Hmm jetzt muss ich noch rausfinden wie man bei ner textarea einen Zeilenumbruch macht..... :mad:
System.getProperty("line.separator")
Kennst du google?
 
antred schrieb:
Neumodischer Hippiekram. Ich glaub' nicht, daß sich das durchsetzen wird.

:D

Ohh hat hier etwa jemand etwas gegen Hippies? :O


ystem.getProperty("line.separator")
Naja habe es so gemacht

PHP:
while (it.hasNext()) {
                String text = it.next().toString();
              
                jTextArea1.setText(text + "\n");
            }
            // while(it.hasNext()){
            //     jTextArea1.append(it.next().toString() + "\n");
            // }

Wobei mich halt wunder das bei setText bleibt er immer in der gleichen Zeile und die neueren Werte überschreiben die Alten und mit append gehts ohne Probleme.
Obwohl es mir sowieso eher darum geht, dass ich auf jeden einzelnen Eintrag zugreifen möchte.
Werde wohl doch eher JList oder Table verwenden, mal schaun was sich dafür anbietet...

Und danke sehr für die Antworten ;)
 
public void setText(String t)

Sets the text of this TextComponent to the specified text.
public void append(String str)

Appends the given text to the end of the document.
Dokumentationen lesen lohnt sich, wenn etwas nicht so funktioniert wie erwartet.
 
Hey..
Hätte noch eine Frage zu ProgressMonitor.

Wollte eben das mir angezeigt wird wie weit die entwicklung bereits ist, jedoch funktoniert das nicht ganz so wie ich möchte.

PHP:
 ProgressMonitor pm = new ProgressMonitor(
                this, "Lade...", "", 0, 100);
         for (int z = 0; z < 100; z++) {
           method1();

         }         
        pm.setMillisToPopup(1);
        pm.setProgress(
                50);
In diesem Fal zeigt er mir zwar nen Monitor an jedoch sehe ich keine veränderung bzw sehe keine 50%;
Laut Oracle Doku hat das wohl mit nem Event Dispatcher zu tun?
Sodas ich es in einem eigenen Thread laufen lassen muss.

Habe es mit ner inneren Klasse so probiert:

PHP:
Thread thread = new Thread (new Runnable() {
    public void run() {
      ProgressMonitor pm = new ProgressMonitor(
                      this, "Lade...", "", 0, 100);
 pm.setMillisToPopup(1);
      for (int i = 0; i <= 100; i++) {
        pm.setProgress(i);
        // Als Ersatz für eine rechen-
        // intensive Operation
        try { Thread.sleep(100); } 
        catch (Exception ex) {}
      }
    }
  });
  thread.start ();
Jedoch öffnet sich der Monitor erst gar nicht und die Methode in der SChleife wird auch net ausgeführt.

Zudem habe ich es auch noch so probiert:

PHP:
 Thread t=new Thread(this);
     t.start();

  @Override
    public void run(){
         ProgressMonitor pm = new ProgressMonitor(
                this, "Lade...", "", 0, 100);
         for (int z = 0; z <100; z++) {
           method();

         }         
        pm.setMillisToPopup(1);
        pm.setProgress(
                50);
    }
Da passiert halt auch nichts, aber das wird wohl auch nicht gehn solange ich keine eigene Klasse für den Monitor schreibe und diese dann dem new Thread() übergebe?....
 
Zu 1: Du setzt den Fortschritt außerhalb der Schleife, also wenn die Arbeit schon beendet ist.
Zu 2: Der Code sollte funktionieren. Bekommst hier vielleicht einen Compilerfehler wegen dem ProgressMonitor(this ?
Zu 3: Siehe 1
 
1,3) Das muss doch egal sein.
Schließlich habe ich dann setProgress(50) geschrieben, dh das der Balken dann bei 50% stehen müsste.

Okayy
Habe mal das this weggemacht
Ich dachte eigentlich das ich ProgressMonitor nehme damit ich keinen eigenen Frame machen muss.
Ich habe die UI per Netbeans generiert sprich es wird nur von nem JFrame geerbt.
Wie kann ich denn dabei auf dieses zugreifen?

Aber da kommt nochn Fehler.
Wenn ich jetzt anstatt der SChleife meine Liste nehme, muss ich diese final deklarieren.
Wenn ich vor dem Thread abfrage wie viele Elemente diese besitzt sind welche drin.
Wenn ich das allerdings nochmal innerhalb des Threads abfrage hat meine Liste einen Wert von 0;
Dabei befindet sich innerhalb der Inneren Methode nur die Schleife und eine Methode die aufgerufen wird.
Weshalb? oO
Falls es relevant ist:
Nach dem thread.start() ist die erste Methode welche aufgerufen wird die Methode welche die Liste löscht.

Ähh mir ist gerade eingefallen das dann der Thread ja extra abgearbeitet wird, also wie kann ich verhindern das zuerst die Liste gelöscht wird?
 
Zuletzt bearbeitet:
Schattenfänger schrieb:
1,3) Das muss doch egal sein.
Schließlich habe ich dann setProgress(50) geschrieben, dh das der Balken dann bei 50% stehen müsste.
Stimmt. Ich vermute aber, dass deine Methode sich zu schnell beendet. D.h der Thread, in dem ProgressMonitor erstellt wurde, ist schon beendet, bevor dieser sich selbst im Dispatcher-Thread erstellen konnte und wird damit aus dem Speicher entfernt, da es keine Referenz mehr auf diesen gibt. Bau' mal ein Thread.sleep() ein und schau' ob er dann sichtbar wird.

Schattenfänger schrieb:
Falls es relevant ist:
Nach dem thread.start() ist die erste Methode welche aufgerufen wird die Methode welche die Liste löscht.
Das ist sogar SEHR relevant und zeigt, dass du Threads nicht verstanden hast. Nach thread.start() existieren zwei Threads, die beide gleichzeitig auf der Liste arbeiten. Du müsstest den Zugriff synchronisieren, damit dein Programm korrekt arbeitet. Natürlich darf der eine Thread die Liste auch nicht leeren, wenn sie von einem anderen Thread gebraucht wird.
 
Das ist sogar SEHR relevant und zeigt, dass du Threads nicht verstanden hast. Nach thread.start() existieren zwei Threads, die beide gleichzeitig auf der Liste arbeiten. Du müsstest den Zugriff synchronisieren, damit dein Programm korrekt arbeitet. Natürlich darf der eine Thread die Liste auch nicht leeren, wenn sie von einem anderen Thread gebraucht wird.

Ehmm ja hab wohl zu spät auf editieren gedrückt ist mir auch noch eingefallen.
Ja, habe eigentlich nie was mit Threads zu tun.

Hab das jetzt so gemacht:
PHP:
if(!thread.isAlive()){lösche}
Passt das so oder kann es so noch zu Problemen kommen?
 
Ich glaube nicht, dass das die Lösung ist. An welcher Stelle soll das stehen? Doch wohl nicht direkt hinter thread.start()?
 
Jop, hat nicht richtig funktioniert.

thread.join() funktioniert
Jedoch wird mir der progressmonitor nicht angezeigt.
es öffnet sich nur der frame und nachdem die daten verarbeitet sind sehe ich ihn endlich auf 100%. Bei den gleichen Daten.
hmmmm
 
thread.join() blockiert den Dispatcher-Thread von dem du ja deinen Arbeits-Thread gestartet hast. Ergo hat dieser gar keine Zeit, irgendwelche Dialoge anzuzeigen. ;)

Warum leerst du die Liste nicht von deinem Arbeits-Thread aus? Also entweder "direkt" oder du ruft eine Methode in deinem Hauptprogramm auf, die evtl. noch weitere Arbeiten erledigt, u.a. die GUI aktualisieren (Achtung, dafür brauchst du wieder den Dispatcher-Thread)
 
Ja, danke hab ich auch bemerkt......
Aber trotzdem versteh ich nicht wieso es unterbrochen wird wenn ich join() verwende obwohl es ja in nem eigenen Thread läuft.

Hab das Liste leeren in den run gepackt und geht auch, aber kann mM auch keine endgültige Lösung sein.
Habe jetzt geschaut
und notify/wait wäre für meine zwecke eigentlich ganz gut
Aber da die Methode von Netbeans generiert wurde kann ich die nicht synchronized setzen wodurch ich nen Fehler bekomme :mad:
 
Mit Thread.join() wird der aktuelle Thread so lange blockiert, bis der Thread, auf den gewartet wird, beendet ist. Da du die Methode aus dem Dispatcher-Thread heraus aufrufst, kann dieser eben nichts zeichnen.

Wenn sichergestellt ist, dass deine Liste nur von einem Thread gleichzeitig genutzt wird, brauchst du keine Synchronisation. Ein wait/notify bringt dir nichts, wenn du es vom Dispatcher-Thread aus machst, da du diesen wieder blockieren würdest.

Ein synchronized gehört auch nicht in die UI-Elemente. Durch den Dispatcher-Thread ist schon sichergestellt, dass hier nichts mehr synchronisiert werden muss, da es nur ein Thread gibt der auf den Elementen arbeitet (bzw. arbeiten sollte).

Du kannst dir ja mal den SwingWorker anschauen.
 
Zurück
Oben