Data communication between Java programs and other processes

Source: Internet
Author: User

Java programs can start other applications, this process started in Java is called a child process, the Java program that initiates the child process is called the parent process, in fact, the parent process is a Java virtual machine
1, in the Java program can use the Process class instance object to represent the child process, the child process standard input and output is no longer connected to the keyboard and the monitor (that is, no longer receive keyboard input, and the monitor output

is connected to an output stream and an input stream object of the parent process in the form of a pipeline flow
2. Call the Getoutputstream and getInputStream methods of the process class to get the output stream and the input stream object connected to the child process. What the child process reads from the standard input is the parent process

Through the output stream object written to the data in the process pipeline between them, the standard output data written by the child process is passed through the process pipeline between them into the parent process's input stream object, the parent process

What is read from this input stream object is the data that the child process writes to the standard output
Programming Example: Starting the Java.exe command in the Testinout class executes another mytest class, testinout and MyTest pass data to each other through a pipeline between processes
Testinout starts two threads, one keeps sending data to the mytest, and the other keeps reading mytest writeback data.
Import java.io.*;
Class Test implements runnable{
Process p = null;
Public test () throws Exception
{
p = runtime.getruntime (). EXEC ("Java MyTest"); Start child process, this program does not exist there will be problems!
New Thread (This). Start (); When you start a thread, with new test (), because in the constructor, two instance objects are created, thread invokes the Run method in the second object, and P of the Run method call is the member variable in the second object. The p called by the Send method is the member variable in the first Test object, so that two P does not match. There is also the ability to generate infinite recursion, because in the constructor, the constructor is called once, so the construction method should be replaced with this
}
public static void Main (string[] args) throws exception{
Test ts = new test (); When the object is created, the child process starts, and the receiving thread initiates the
Ts.send ();
}
public void Send () throws exception{
try{
OutputStream Ops = P.getoutputstream (); Send, first to connect an output stream object
while (true)
{
Ops.write ("help/r/n". GetBytes ()); Write String
}
}catch (Exception e) {e.printstacktrace ();}
}

public void Run () {
try{
InputStream in = P.getinputstream (); Receive, first to get the input stream object
BufferedReader bfr = new BufferedReader (new InputStreamReader (in)); In order to read one line at a time, you can use BufferedReader this wrapper class to wrap the InputStream class, packaging This class needs to be converted into a character stream of bytes before packaging, check help!
while (true) {
String strLine = Bfr.readline ();
System.out.println (StrLine);
}
}catch (Exception e) {e.printstacktrace ();}
}
}
Import java.io.*;
public class mytest{
public static void Main (string[] args) {
while (true)
{
try{
System.out.println ("Hi:" +
New BufferedReader (New InputStreamReader (system.in)). ReadLine ()); To read the parent process data
}
catch (Exception e)
{
E.printstacktrace ();
}
}
}
}
"Note" Each execution starts a child process that is still running after the parent process is forcibly terminated with CTRL + C in the compiler. BufferedReader implementation is a bit problematic, the parent process has been terminated, the child process reads, BufferedReader should throw an exception, let the program end! Based on BufferedReader's JDK help, we make some modifications to the child Process code so that the parent process terminates and the subprocess ends. Then the test class can make similar changes so that it can no longer print null without stopping.
Import java.io.*;
public class mytest{
public static void Main (string[] args) {
while (true)
{
try{
String strLine = new BufferedReader (new InputStreamReader (system.in)). ReadLine ();
if (strLine! = null)
{
System.out.println ("Hi:" + strLine); To read the parent process data
}
else{
Return
}
}
catch (Exception e)
{
E.printstacktrace ();
}
}
}
}
"Thinking" in the example above we can see the data loss situation, such as the string does not print the full line, this is because the pipeline is a certain capacity, the capacity of the pipeline is the PipedInputStream pipeline input buffer size, if the buffer is full, The output program is still writing data, it may be the first few data to the top out, then if the receiver is slow, then it is possible to read less content back! After the buffer is full, how does it handle the previous data, or will it block the write process, or throw an exception?

After verifying that the pipeline buffer is full, the following situation occurs:
1. When new data is written, the data is lost by extruding the most front-written
2, PipedInputStream connected to the PipedOutputStream can not write new data, Pipedoutputstream.write method is in a blocking state
3, PipedInputStream connected to the PipedOutputStream can not write new data, Pipedoutputstream.write method throws an exception

"Program Validation"
1, let the child process do not read the data (MyTest Class), the empty loop, then the parent process in the pipeline to write, it will certainly occur blocking. At this time to run the program, the program stalled, not clear what the situation, but it is certain that the buffer is full after the exception is not thrown. Note that there are child processes in the system process, although the parent process we ended with CTRL + C
2, in the parent process of the Send method to print a line number, that is, each time the loop, so you can know whether it is blocked or continue to write, because in the first step, we can only see the program stalled, what information is not. You will notice that the line number is printed to a certain point when the program stops (the buffer is related to the machine?) because the line number stops after each machine is running. I was in the 1366),

This means that when the pipeline buffer is full, the writing process is blocked, rather than putting the previous data on top. Note that there are child processes in the system process, although the parent process we ended with CTRL + C

After verifying that the pipeline buffer is full, we will then solve the problem of data loss
1, restore the code, let the child process (MyTest Class) continue to read data, note that the write process according to the above verification should be no problem, it will not lose data
2, observation results, this situation should not be read lost data, if read lost data how it will "hi:" This we added in the sub-process characters printed out, since it all read "Hi:", that

It should not be lost information, the loss of information should be the sub-process read the contents of the strline is not the complete information
3, now can basically determine that the problem occurred mytest this class, and its effective code is not long, the content of the printing should be no problem, then the problem is focused on string strLine = new

BufferedReader (New InputStreamReader (system.in)). ReadLine (); on this sentence. To solve the problem of this sentence, generally not very good grasp, but in this case we ourselves

When the analysis does not come out of the reason, you can use the code in other ways to write.
4, put this sentence out of the loop, because we can not find the reason, the code will be split to try, a different location to try, because the code is relatively simple. such as defining a variable bfr, and then in the loop

Call the ReadLine method, which is
BufferedReader bfr = new BufferedReader (new InputStreamReader (system.in));
while (true)
{
String strLine = Bfr.readline ();
}
5, then found that the program is normal, no loss of information, this is why? Let's move the code to a location.
6. Then look back at the original code, new BufferedReader (New InputStreamReader (system.in)) in the loop, each time the loop is created to create a BufferedReader object once. and lose

into the output stream should call them close method to close the system-created stream resource (not the Java-created object, but the system-created resource). When you close a Java-created object, this stream resource object does not necessarily

Will be released. This runs more times, the accumulation of such resources more and more, the system is a problem.
7. Think about what happens when we create an object in the loop and then call the Close method.
while (true)
{
BufferedReader bfr = new BufferedReader (new InputStreamReader (system.in));
String strLine = Bfr.readline ();
...
Bfr.close ()
}
8, again compiled run, found that the compiler only printed a line of information, and then reported IO exception, the pipeline has ended, this is why?
9, re-analysis of this problem, if the flow stack in the top level of the stream object, it will close the flow stack all the underlying flow, we call Bfr.close (), then it will even InputStreamReader and system.in associated with the flow resources are closed off. The second cycle, System.in associated with the resource has been closed, then there is no, and, this exception when the parent process is reported, and the child process will system.in a close, the parent process will return 1, think that they are finished, so system.in can not easily shut down
10, so the method of solving data loss is to put bufferedreader bfr = new BufferedReader (new InputStreamReader (system.in)) outside the loop. So pay attention to where the program code is placed. In addition, when we start a child process with a Java virtual machine, we must be aware that the child process must end at the end of the parent process. Remember to call the Destroy method of the process class to end the run of the child process (because IO returns a null in this example, so we use NULL to determine that the destroy method should generally be used to end the subprocess). And it is common to create child processes in a program, such as JCreator, which calls Javac.exe and Java.ext
"Hint" to have a thought, in programming, the mind is not a line of code, but an object, the program each run a sentence each object is doing, is not more objects, and less objects, the state of the object and how to change, should think like this.

Improve the operational efficiency of the program
1, for (int i=0;i<str.length (); i++)
{..}

2, int len = Str.length ();
for (int i=0;i<len;i++)
{..}
The 2nd method is more efficient than the 1th because the length method is called to detect string lengths for each of the 1th loops

3, byte[] buf = new byte[1024]
while (true) {:}

4, while (true)
{byte[] buf = new byte[1024];}
The 3rd method is more efficient than the 4th because each iteration of the 4th cycle creates an array object and accounts for more memory

Data communication between Java programs and other processes

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.