On Saturday 15 September 2001 11:45, Andre Best wrote:
Hi Liste,
hat hjemand ne Idee, warum folgendes Programm in java unter Linux Probleme macht, wenn ein pipe-Operator an den auszuführenden String angehängt wird?
java UnixList "ls -l" funzt !!!
java UnixList "ls -l | lpr" funzt NICHT!!!
Hi Andre, fuer das "Piping" empfiehlt sich der Einsatz von Threads nach dem "Producer-Filter-Consumer"-Prinzip. Der Grund, warum Dein Beispiel nicht funktioniert, ist die Tatsache, dass "ls -l" ausgefuehrt wird und der InputStreamReader "vergisst", was er gerade getan hat. Irgendwie verhungert der Stream und nichts passiert. Du musst also die einzelnen Input/Output-Prozesse auch in Java trennen. Wir hatten das Problem auch einmal und haben es mit Threads bewaeltigt. Sollte eder Producer die Daten schneller bereitstellen, als der Consumer Sie verarbeiten kann, wird die "write"-Operation des Consumers geblockt. Es existieren bequeme Klassen (PipedInputStream, PipedOutputStream) zur Implementierung der "gepipe'ten" Kommunikation. Der Producer erzeugt einen Stream aus Bytes. Wird ein Stream aus Unicode-Zeichen erzeugt, muessen die Klassen PipedReader und PipedWriter verwendet werden. Der Producer sendet die Resultate an den Filter, der sie entweder weiter modifiziert, oder unbearbeitet an den Consumer weitergibt. Der Filter und der Consumer wissen nicht woher das Input kommt. Der Vorteil der Pipes ist, das die mehrere Threads miteinander verbunden werden koennen, ohne synchronisiert zu werden. 1. PipedInputStream() - erzeugt einen neuen "gepipe'ten" input stream. 2. PipedInputStream(PipedOutputStream out) - erzeugt einen neuen "gepipe'ten" input stream, der Daten vom "gepipe'ten" output stream liest. 3. PipedOutputStream() - erzeugt einen neuen "gepipe'ten" output stream. 4. PipedOutputStream(PipedInputStream in) - erzeugt einen neuen "gepipe'ten" input stream, der Daten in "gepipe'ten" input stream schreibt. 5. void connect(PipedOutputStream out) - haengt einem output stream an, von dem die Daten gelesen werden sollen. 6. void connect(PipedInputStream in) - haengt einem input stream an, zu dem die Daten geschrieben werden sollen. Den unten stehenden Code brauchst Du nur noch auf Deine Beduerfnisse anpassen und dann kann es losgehen. Sollte das alles nicht das sein, was Du moechtest, lass es mich einfach wissen. Vielleich ueberlegen wir uns einfach etwas anderes. Viel Erfolg ------------------------------ import java.util.*; import java.io.*; public class PipeTest { public static void main(String args[]) { try { /* pipe setup */ PipedOutputStream pout1 = new PipedOutputStream(); PipedInputStream pin1 = new PipedInputStream(); PipedOutputStream pout2 = new PipedOutputStream(); PipedInputStream pin2 = new PipedInputStream(); /* thread construction */ Producer prod = new Producer(pout1); Filter filt = new Filter(pin1, pout2); Consumer cons = new Consumer(pin2); /* start threads */ prod.start(); filt.start(); cons.start(); } catch (IOException e) {} } } class Producer extends Thread { public Producer(OutputStream os) { out = new DataOutputStream(os); } public void run() { while(true) { try { // put producer code here. } catch (Exception e) { // error handling. } } } private DataOutputStream out; // producer output } class Filter extends Thread { public Filter(InputStream is, OutputStream os) { in = new DataInputStream(is); out = new DataOutputStream(os); } public void run() { // Do what ever you want with producer output } private DataInputStream in; private DataOutputStream out; } class Consumer extends Thread { public Consumer(InputStream is) { in = new DatainputStream(is); } public void run() { // do what ever you want with filter output } private DataInputStream in; }