2009-07-15 10 views
9

Ich habe einige Code geerbt:Process Builder waitFor() Ausgabe und Datei öffnen Einschränkungen

Process p = new ProcessBuilder("/bin/chmod", "777", path).start(); 
p.waitFor(); 

Grundsätzlich gibt es für einige alte und hoch Grund Voodoo Basis für die Speicherung von Schlüssel/Wert-Paare auf der Festplatte als Dateien. Ich möchte nicht wirklich darauf eingehen.

Allerdings bin ich mit einem Bündel von IO Ausnahmen links:

Exception :Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files 
Message: Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files 

Und durch ein Bündel ich in den Bereichen 10k bedeuten - Millionen

ich das Gefühl, das waitFor Anruf bekommen war zu stoppen Diese entstehen dadurch, dass ich darauf warte, dass der Prozess sie beendet und zurückkehrt, aber ich denke, dass chmod ein Ergebnis zurückgibt, bevor die Datei tatsächlich geschlossen wird. Weiß jemand, ob das der Grund für diese Ausnahmen wäre?

Meine andere Neigung ist, dass das Öffnen und Schließen von Tausenden von Dateien nicht schnell genug auf dem Java-Ende passiert und dass da etwas anderes vor sich geht, vielleicht so etwas wie eine Art von Dateipuffer, der nicht ist wird gelöscht, wenn fw.close() aufgerufen wird.

Ich bin ziemlich neu in Java und das war eine Hölle seltsam, die mich ratlos hat. (gerne läuft die app noch irgendwie .. nach dem ausspucken eine sehr große log-datei ist das)

Kann jemand anders über eine Möglichkeit nachdenken, um diese zu umgehen, löschen Puffer oder erhöhen die Dateien öffnen Grenze zu etwas, wo der JVM kann Schritt halten mit sich selbst (vorausgesetzt, dass das Problem ist)

+0

Was ist Ihr Ziel-Betriebssystem (und Version).Siehe dies: http://unix.derkeiler.com/Newsgroups/comp.unix.solaris/2007-02/msg00873.html –

+0

debian, es scheint aus uname gelöscht werden. wird spätestens stabil sein. – Louis

Antwort

14

Ich nehme an, dass Sie diese chmod Befehle in einer Schleife ausführen - sonst sehe ich nicht, warum Sie so viele Ausnahmen bekommen würden. Es ist möglich, dass Sie einen Deadlock erreichen, weil Sie die Ausgabe der erzeugten Prozesse nicht lesen. Das hat mich in den letzten Tagen sicherlich wieder gebissen.

Ihren Code-Snippet zu dem obigen Muster ändern:

try { 
    ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path);  
    pb.redirectErrorStream(true); // merge stdout, stderr of process 

    Process p = pb.start(); 
    InputStreamReader isr = new InputStreamReader(p.getInputStream()); 
    BufferedReader br = new BufferedReader(isr); 

    String lineRead; 
    while ((lineRead = br.readLine()) != null) { 
     // swallow the line, or print it out - System.out.println(lineRead); 
    } 

    int rc = p.waitFor(); 
    // TODO error handling for non-zero rc 
} 
catch (IOException e) { 
    e.printStackTrace(); // or log it, or otherwise handle it 
} 
catch (InterruptedException ie) { 
    ie.printStackTrace(); // or log it, or otherwise handle it 
} 

(Kredit: this site) und sehen, ob das die Situation hilft.

+0

Versucht dies, die gleichen Ausnahmen auftreten – Louis

+0

Ich denke, ich habe es gelöst, überprüfen Sie meine Antwort in ein paar Minuten - nur auf Tests warten, um zu überprüfen – Louis

+0

Ok wählte Ihre Antwort als es in der Lösung benötigt , überprüfe, ob meine Post die benötigten zusätzlichen Zeilen enthält. – Louis

0

Es scheint unwahrscheinlich, dass der Prozess tatsächlich abgeschlossen wäre, ohne die Dateien zu schließen. Könnte das in einer sehr großen Anzahl von Threads passieren? Oder vielleicht sind einige von ihnen nicht wirklich abgeschlossen (dh, es hängt in einigen Fällen auf warten)?

Sonst denke ich, dass Sie mit der Erhöhung der Grenze für offene Dateien stecken bleiben werden. Angenommen, dies ist ein Unix-ähnliches System, ist der Befehl "ulimit" wahrscheinlich das, wonach Sie suchen.

+0

eingestellt auf unbegrenzt: \ – Louis

0

Wenn Sie JAVA 6 verwenden, können Sie auch die neuen Setter (zum Lesen, Schreiben, Ausführen) für das File-Objekt ausprobieren. Könnte langsamer sein, aber es sollte funktionieren.

6

Danke für die Hilfe Jungs, dies sollte eine Menge von Seltsamkeit aussortieren, die anderswo wegen es geht.

mit Ihrem (Vinay) Beispiel und die Stream-Schließungen:

try{ 
    fw.close(); 

    ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path); 

    pb.redirectErrorStream(true); // merge stdout, stderr of process 
    p = pb.start(); 

    InputStreamReader isr = new InputStreamReader(p.getInputStream()); 
    BufferedReader br = new BufferedReader(isr); 

    String lineRead; 
    while ((lineRead = br.readLine()) != null) { 
    // swallow the line, or print it out - System.out.println(lineRead); 
    } 

} catch (Exception ioe) { 
    Logger.logException(Logger.WARN, ioe.getMessage(), ioe); 
} finally { 
    try { 
    p.waitFor();//here as there is some snipped code that was causing a different 
       // exception which stopped it from getting processed 

    //missing these was causing the mass amounts of open 'files' 
    p.getInputStream().close(); 
    p.getOutputStream().close(); 
    p.getErrorStream().close(); 

    } catch (Exception ioe) { 
    Logger.logException(Logger.WARN, ioe.getMessage(), ioe); 
    } 
} 

habe die Idee von John B Mathews post.

+0

hinweis: immernoch macht es keinen sinn, warum das warten und schließen der eingangsströme würde nicht gerade gut, aber ich denke es ist java ... – Louis

+1

Guter Fang, jim, aber ich sehe immer noch ein Problem in Ihrem 'endlich' . Ich denke, Sie müssen jeden der 'close' Aufrufe in ihrem eigenen' catch' haben, andernfalls, wenn eine Ausnahme auftritt, wenn Sie 'p.getInputStream.close()' machen, werden Sie die anderen nicht schließen können. Das Problem scheint jetzt verschwunden zu sein, könnte aber später wiederkommen. –

+0

guter Punkt. Danke – Louis