Мне нужно извлечь входной поток процесса после его запуска. Сегодня я могу получить исходную информацию, но метод не возвращается, пока я не закрою приложение (в этом случае приложение запускается процессом: gedit и firefox). Я имею в виду, я знаю, что он просто вернется после закрытия процесса, но я хотел бы получить обходное решение, чтобы получить это до закрытия процесса. Смотрите мой код ниже.Как извлечь входной поток до завершения процесса
public class ProcessInvokerExtractingProcessInformation {
public static void main(String args[]) {
try {
Process pOpenApp = new ProcessBuilder(new String[] { "gedit",
"/home/thais/Documents/gedit_doc1" }).start();
printInformation("pOpenApp", pOpenApp);
// * just for testing error message and input stream
Process openFirefox = new ProcessBuilder(new String[] { "firefox" })
.start();
printInformation("lsInstruction", openFirefox);
deleteProcess(pOpenApp);
deleteProcess(openFirefox);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// method for testing information we can see regarding the process
public static void printInformation(String id, final Process process) {
System.out.println(" Process " + id + ":");
//tried to run in a separated thread but didn't work as well
Runnable r = new Runnable(){
public void run(){
System.out.print("\n Process error message -> ");
printScannedStream(process.getErrorStream());
System.out.println("\n Process input message -> ");
printScannedStream(process.getInputStream());
}
};
Thread a = new Thread(r);
a.start();
/* other approaches to print the streams, tried before
StringWriter writer = new StringWriter();
try {
PrintWriter pWriter = new PrintWriter(new
BufferedOutputStream(process.getOutputStream()));
pWriter.write("Hi"); pWriter.flush(); System.out.println(
" Process output stream is for writing so there is no information "
);
*//*
InputStreamReader isr = new InputStreamReader(
process.getErrorStream());
BufferedReader br = new BufferedReader(isr);
System.out.print("\n Process error message -> ");
while (br.readLine() != null) {
System.out.print(br.readLine());
}
System.out.println("\n Process input message -> ");
isr = new InputStreamReader(process.getInputStream());
br = new BufferedReader(isr);
while (br.readLine() != null) {
System.out.print(br.readLine());
}
br.close();
isr.close();*/
/*
* IOUtils.copy(process.getErrorStream(), writer, null);
* System.out.println(" Process error message -> " +
* writer.toString());
*
* IOUtils.copy(process.getInputStream(), writer, null);
* System.out.println(" Process input stream message -> " +
* writer.toString()+"\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
}
/**
* Method that close all streams and after destroy the process It's
* important to close the streams to avoid file descriptions leaking
*
* @param process
*/
public static void deleteProcess(Process process) {
try {
process.getInputStream().close();
process.getOutputStream().close();
process.getErrorStream().close();
process.destroy();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void printScannedStream(java.io.InputStream is) {
try {
Scanner scanner = new Scanner(is);
while(scanner.hasNext()) {
System.out.print(scanner.next());
}
} catch (java.util.NoSuchElementException e) {
e.printStackTrace();
}
}
}
Привет, Николай, большое вам спасибо. Я пробовал ваш код, но на самом деле он работал как мой. Я имею в виду, что он печатает информацию о процессе до закрытия процесса, но программа все еще ждет завершения процесса для продолжения. Я хотел что-то, что не остановило бы приложение. Я имею в виду, он печатал бы, если бы что-то печаталось и после этого продолжал приложение регулярно. Считаете ли вы, что это возможно? –
Привет, Николай, на самом деле теперь ваш код работает идеально для меня. Мне просто пришлось удалить waitFor(), так как я использую этот метод для нескольких процессов. –
А также, сравнивая с моим кодом, я заметил, что логика была схожа. Моя ошибка заключалась в том, что я пытался увидеть errorStream и inputStream в том же запущенном потоке. Создание двух потоков, по одному для каждого потока, решило проблему. Еще раз большое спасибо! –