1 problems encountered: Java to start an external program, the external program has been suspended does not quit.
2 Workaround: Start two threads, read the standard output of external program and standard error output respectively.
3 Reference Code:
String db3file = Fileutil.connectfile (Workdirstr, fileName); String cmd = "Java-jar" + jarfile.getabsolutepath () + "" + filename;//+ "Debug"; DB3 requires a relative path to add debug parameters to view the makefile String expectzipfile = db3file+ ". 4.zip";//desired zip file Logger.info ("DB3 Generate ZIP packets, cmd={},
Expect to generate zip file ={}, workdir={} ", cmd, Expectzipfile, Workdir);
Process process = Runtime.getruntime (). EXEC (cmd, null, WORKDIR); Read the error stream and the input of normal stream, otherwise it will block, can not get the result correctly inputstream stderr = Process.geterrorstream ();
Gets the standard error output stream Getinputdata (stderr, true);
InputStream Inpbuildtar = Process.getinputstream ();//Get Standard output stream Getinputdata (Inpbuildtar, false);
Boolean isprocessfinsh = Process.waitfor (timeunit.seconds);
if (!isprocessfinsh) {logger.info ("DB3 conversion zip package, mapmaker.jar--failure, program 20 seconds not completed, workdir={}", WORKDIRSTR);
return null; /** * Read stream data * * @param inputstream * * private static void Getinputdata (Final InputStream InputStream, Boolean isError) {//new thread read the created process log must be this way Http://blog.csdn.net/mengxingyuanlove/article/details/50707746 thread thread = new Thread (new Runnable () {public void run () {Logger.info) ("Start read process flow, is
error={} ", IsError);
try {String msg = ioutils.tostring (InputStream, Charset.defaultcharset ());
if (isError) {logger.error ("DB3 convert zip package, Mapmaker.jar return ={}", msg);
else {logger.info ("DB3 convert zip package, Mapmaker.jar return ={}", msg); The catch (IOException e) {logger.error ("DB3 conversion zip package, mapmaker.jar error, errormsg=" + e.getmes
Sage (), E);
finally {ioutils.closequietly (inputstream);
Logger.info ("end read process stream, iserror={}", IsError);
}
});
Thread.Start (); }
4 Analysis of the problem
View the Help documentation for Java.lang.Process.getInputStream (), with a description "Returns the input stream connected to the normal output of the subprocess ."。 The input stream returned by the method is the output stream connected to the child process.
As shown in the figure above, the subprocess (that is, the process you are starting with Java) writes the data to the output stream, it is placed in a buffer, and then the Java process is read by the corresponding input stream. But when the buffer is full, the subprocess stops (the phenomenon is that the subprocess does not exit).
If your Java program does not read the data, when the child process output is very young, because there is a cache, the child process will not block. But when the child process output a lot, the buffer is full, it will block.
The error output stream is the same.