2012-01-05 36 views
9

ProcessBuilder tarafından oluşturulan bir işlemin çıktısını başka bir ProcessBuilder tarafından oluşturulan başka bir işleme iletmek mümkün mü? Örneğin, ben bu kabuk komutu çalıştırmak çalışıyorum eğer:başka bir ProcessBuilder ürününe bağlanması

ls | grep build.xml 
Ben ProcessBuilder, bunu nasıl

?

Process process = Runtime.getRuntime().exec("ls"); 
InputStream is = process.getInputStream(); 
byte[] buf = new byte[1000]; 
is.read(buf); 
String parameter = new String(buf); 
System.out.println("grep build " + parameter); 

Process proc2 = Runtime.getRuntime().exec("grep build " + parameter); 
InputStream is2 = proc2.getInputStream(); 
byte[] buf2 = new byte[1000]; 
is2.read(buf2); 
String result = new String(buf2); 
System.out.println("proc2 result: " + result); 

ama farklı sonuç ben kabuğunda doğrudan komut dosyası çalıştırdığınızda karşılaştırmak üretir: @erdinc önerildiği gibi

, bu çalıştı. Nerede yanlış yaptım? Çözüldü

: olarak parametre ikinci Süreci geçmesi daha Sen getInputStream yöntemi kullanabilirsiniz Philipp Wendler çözümü

cevap

6

sahip çözelti ile sorun ls çıktısına sadece ilk 1000 bayt okur ve grep iletir olmasıdır. Önceden ls çıkış miktarını bilmediğiniz için, bitene kadar yinelemeli olarak okumalısınız.

İşte grep için her çıktı satırı gönderir BufferedReader kullanarak bir çözümdür: Eklemek gerekir Tabii

Process lsProcess = Runtime.getRuntime().exec("ls"); 
BufferedReader lsOutput = new BufferedReader(new InputStreamReader(lsProcess.getInputStream())); 
Process grepProcess = Runtime.getRuntime().exec("grep build.xml"); 
BufferedWriter grepInput = new BufferedWriter(new OutputStreamWriter(grepProcess.getOutputStream())); 

String line; 
// read each line from ls until there are no more 
while ((line = lsOutput.readLine()) != null) { 
    // and send them to grep 
    grepInput.write(line); 
    grepInput.newLine(); 
} 

// send end-of-file signal to grep so it will terminate itself 
grepInput.close(); 

uygun hata işleme burada. Okuyucu ve Yazıcıyı atlayabilir ve bu çözüm çok yavaşsa, byte[] dizilerini doğrudan girişten çıkış akışına geçirebilirsiniz. Bununla birlikte, çok daha iyi bir çözüm, dosya sisteminde bir dosya aramak için ls ve grep kullanmamak, ancak uygun Java API'sini kullanmak değildir. Örneğin, ilgilendiğiniz dizinin bir File nesnesi oluşturursanız, bu dizindeki tüm dosyaları listelemek için çeşitli listFiles yöntemlerini kullanabilirsiniz. Bu yöntem daha kolay, taşınabilir, daha az hata eğilimli ve muhtemelen daha hızlıdır.

+0

çözümünüz çalışıyor! teşekkür ederim Philipp: D Aslında bu kodu chasen ve moses (makine çeviri araçları) gibi birkaç harici uygulamayı çağırmak için kullanacağım. Ls | grep örneği sadece soruları basitleştirmek için yapılmıştı, ancak öneri için teşekkürler: D Çözülen soruyu işaretleyeceğim ve çözümünüzü üstleneceğim. – ndriks

0

bakınız. Örnek kod;

 process = Runtime.getRuntime().exec("ls"); 
     InputStream is = process.getInputStream(); 
     byte[] buf = new byte[1000]; 
     is.read(buf); 
     String parameter = new String(buf); 
     System.out.println(parameter); 
     Runtime.getRuntime().exec("grep build.xml " + parameter); 
+0

Ancak "ls" giriş akışı "grep" işlemine nasıl geçilir? İşlemde setInputStream yöntemini bulamıyorum. Ayrıca ProcessBuilder ile yapılabilir? – ndriks

+0

Çözümünüzü @erdinc denedim, ancak komutun doğrudan kabuk içinde çalıştırılmasıyla karşılaştırılan farklı sonuç üretir. Ne yaptığımı göstermek için soruyu düzenledim. FYI, lps sonucunu parametre olarak çalıştırmaya çalışmıyorum, ancak ls sonucunu grep işlemine aktarmaya çalışıyorum. – ndriks