Giriş/Çıkış Akışı ile Java Süreci
Aşağıdaki kod örneği aşağıda var. echo test
yani bash kabuğu için bir komut girin ve sonucu olabilir sayede geri echo. Ancak, ilk okuduktan sonra. Diğer çıkış akışları çalışmıyorsun?
Bu yüzden ya yanlış bir şey mi yapıyorum? Son hedefim /için periyodik olarak bir komut yürütür Dişli bir zamanlanmış görev OutputStream
InputStream
tandem çalışmak zorunda diye bash ve çalışmamaya oluşturuldu. Ayrıca java.io.IOException: Broken pipe
herhangi bir fikir hatayla karşılaşmış?
Teşekkürler.
String line;
Scanner scan = new Scanner(System.in);
Process process = Runtime.getRuntime ().exec ("/bin/bash");
OutputStream stdin = process.getOutputStream ();
InputStream stderr = process.getErrorStream ();
InputStream stdout = process.getInputStream ();
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
String input = scan.nextLine();
input = "\n";
writer.write(input);
writer.flush();
input = scan.nextLine();
input = "\n";
writer.write(input);
writer.flush();
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " line);
}
input = scan.nextLine();
input = "\n";
writer.write(input);
writer.close();
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " line);
}
CEVAP
Öncelikle, hat değiştirilmesi tavsiye ederim
Process process = Runtime.getRuntime ().exec ("/bin/bash");
hatları ile
ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.redirectErrorStream(true);
Process process = builder.start();
ProcessBuilder Java 5'te yeni ve daha kolay harici çalışan işlemleri yapar. Benim görüşüme göre, Runtime.getRuntime().exec()
en önemli gelişme, standart çıktı akımına alt sürecin standart hata yönlendirmek için izin vermektedir. Bu sadece bir InputStream
okuma anlamına gelir. Önce bu, ihtiyacın iki ayrı iş Parçacıkları, bir okuma stdout
ve bir okuma stderr
önlemek için standart hata tampon doldururken standart çıkış tampon boştu (neden çocuk işlem askıda), ya da tam tersi.
Sonra, döngüler iki ()
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " line);
}
işlemin standart çıktısı okur reader
,, döner dosya son ne zaman tek çıkış yolu bu. Bu sadece süreç çıktığında olur. Eğer şu anda işleminden daha fazla çıkış olursa orada dosya sonu gelecek gibi değil. Bunun yerine, sürecin çıkış sonraki satırı için bekleyin ve bu bir sonraki satır kadar döndürür.
Bu döngü ulaşmadan sürecine girdi iki satırlık bir gönderme olduğuna göre, bu iki döngü ilk sürecine girdi bu iki satır sonra çıkıldı bulmazlarsa askıda. Orada başka bir satır okumak için bekleyen oturup, ama asla okumak için başka bir hat olacak.
Kaynak kodu derlenmiş (şu anda Windows üzerindeyim, cmd.exe
ile /bin/bash
değiştirdim ama prensipleri aynı olmalıdır), ve bunu buldum:
- iki satır yazdıktan sonra, ilk iki komutu çıktısı görünür, ama daha sonra program kilitleniyor
- eğer ben yazın desem
echo test
exit
programcmd.exe
işlemden çıkıldığı beri ilk halkanın dışında yapar. Program daha sonra giriş yok sayılır) bir satır, alt işlem zaten çıkıldı beri düz ikinci döngü üzerinde atlar ve çıkışları kendisi için ister. - ben
exit
echo test
, yazarsanız bir IOException bir boru kapalı olma konusunda şikayet alıyorum. Bu beklenen bir durum - giriş, ilk satır işleminden çıkmak için neden, ve hiçbir yerde ikinci satır göndermek için var.
Bir şey istiyor gibisin ne benzer bir numarayı görmüş, üzerinde çalıştığım bir program var. Bu program kabukları bir dizi tuttu, koştu komutları ve bu komutların çıktısını okuyun. Hile kullanıldığı için her zaman yazmak bir 'sihirli' çizgi işaretleri sonunda kabuk komutunun çıktısını ve kullanan belirlerken çıkış komutu gönderdi kabuk vardı bitmiş.
Kod aldım ve aşağıdaki döngü ile writer
atadığı satırdan sonra her şeyi değiştirdim:
while (scan.hasNext()) {
String input = scan.nextLine();
if (input.trim().equals("exit")) {
// Putting 'exit' amongst the echo --EOF--s below doesn't work.
writer.write("exit\n");
} else {
writer.write("((" input ") && echo --EOF--) || echo --EOF--\n");
}
writer.flush();
line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
System.out.println ("Stdout: " line);
line = reader.readLine();
}
if (line == null) {
break;
}
}
Bu yaptıktan sonra, güvenilir bir şekilde birkaç komutları çalıştırın ve her çıktısı bana tek tek geri gelebilirdim.
Satır kabuk gönderilen echo --EOF--
iki komutu var bu komut çıktısı bile komut bir hata sonucu --EOF--
ile sonlandırıldı emin olun.
Tabii ki, bu yaklaşım sınırlamaları vardır. Bu sınırlamalar şunlardır:
- eğer kullanıcı giriş (başka bir kabuk gibi) için bekleyen bir komut girerseniz, program askıda görünüyor
- her işlemi kabuk tarafından işletilen bir yeni satır ile çıkış uçları, varsayar
- bir bit ise komut kabuğu tarafından yürütülüyor 29 ** bir satır yaz olursa iyice karışır.
bash
sözdizimi bir hata ve eğer eşsiz)
ile bir metin girerseniz çıkar bildiriyor.
Bu noktalar bunun bir önemi olmayabilir sen eğer ediyorsan, düşünce olarak çalışan bir zamanlanmış görev olacak sınırlı bir komut ya da bir küçük set komutları olan asla davranır gibi patolojik yollar.
EDİTLinux üzerinde çalışan bu aşağıdaki çıkış işleme ve diğer küçük değişiklikler geliştirmek.
Giriş / çıkış izleme tam bir yığın bas...
Can't başlangıç Eclipse - Java ba...
İnputStream & Çıkış Akışı nedir? Neden...
Yazdırma Java Koleksiyonları Güzel (...
C# 4.0 isteğe bağlı giriş/çıkış ref ar...