我需要在启动后提取进程的输入流。 今天我可以获得初始信息,但是在我关闭应用程序之前该方法不会返回(在这种情况下,应用程序由进程启动: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();
}
}
}
答案 0 :(得分:0)
我有同样的问题,我使用额外的线程解决了它。
class InputHandler implements Runnable {
InputStream input_;
InputHandler(InputStream input) {
input_ = input;
}
public void run() {
try {
int c;
String line = "";
while ((c = input_.read()) != -1) {
if (((char) c == '\r') || ((char) c == '\n')) {
if (!line.isEmpty()) flushString(line);
line = "";
} else
line += (char) c;
}
} catch (Throwable t) {
t.printStackTrace();
}
}
private void flushString(String s) {
// any code to process data from stream
Logger.debug("library: " + getClass().getName() + ": compress: output: " + s);
}
}
Process process = run.exec(ffmpegCmdString);
// read output
InputHandler stderrHandler = new InputHandler(process.getErrorStream());
new Thread(stderrHandler).start();
InputHandler stdoutHandler = new InputHandler(process.getInputStream());
new Thread(stdoutHandler).start();
process.waitFor();