This Java File IO tutorial guides you how to write Java code to run native commands of the host operating system.

Although Java is a cross-platform programming language, sometimes we need to access to something in an operating system dependent way. In other words, we need a Java program to call native commands that are specific to a platform (Windows, Mac or Linux). For example, querying hardware information such as processer ID or hard disk ID requires invoking a kind of native command provided by the operating system. Throughout this tutorial, you will learn how to execute a native command from within a Java program, including sending inputs to and getting outputs from the command.

Basically, to execute a system command, pass the command string to the exec() method of the Runtime class. The exec() method returns a Process object that abstracts a separate process executing the command. From the Process object we can get outputs from and send inputs to the command. The following code snippet explains the principle:

String command = "command of the operating system";

Process process = Runtime.getRuntime().exec(command);

// deal with OutputStream to send inputs
process.getOutputStream();

// deal with InputStream to get ordinary outputs
process.getInputStream();

// deal with ErrorStream to get error outputs
process.getErrorStream();
Now, let’s walk through some real code examples.

The following code snippet runs the ping command on Windows and captures its output:

String command = "ping www.codejava.net";

try {
	Process process = Runtime.getRuntime().exec(command);

	BufferedReader reader = new BufferedReader(
			new InputStreamReader(process.getInputStream()));
	String line;
	while ((line = reader.readLine()) != null) {
		System.out.println(line);
	}

	reader.close();

} catch (IOException e) {
	e.printStackTrace();
}
It gives the following output in the standard console:

Pinging codejava.net [198.57.151.22] with 32 bytes of data:
Reply from 198.57.151.22: bytes=32 time=227ms TTL=51
Reply from 198.57.151.22: bytes=32 time=221ms TTL=51
Reply from 198.57.151.22: bytes=32 time=220ms TTL=51
Reply from 198.57.151.22: bytes=32 time=217ms TTL=51

Ping statistics for 198.57.151.22:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 217ms, Maximum = 227ms, Average = 221ms
 

1. Getting Standard Output

For system commands that produce some output as result, we need to capture the output by creating a BufferedReader that wraps the InputStream returned from the Process:

BufferedReader reader = new BufferedReader(
		new InputStreamReader(process.getInputStream()));
Then invoke the readLine() method of the reader to read the output line by line, sequentially:

String line;
while ((line = reader.readLine()) != null) {
	System.out.println(line);
}

reader.close();


We can also use a Scanner to read the command’s output, for example:

Scanner scanner = new Scanner(process.getInputStream());
scanner.useDelimiter("\r\n");

while (scanner.hasNext()) {
	System.out.println(scanner.next());
}

scanner.close();
 

2. Getting Error Output

A command is not always executed successfully, because there would be a case in which the command encounters an error. And typically, error messages are sent to the error stream. The following code snippet captures the error input stream returned by the Process:

BufferedReader errorReader = new BufferedReader(
		new InputStreamReader(process.getErrorStream()));
while ((line = errorReader.readLine()) != null) {
	System.out.println(line);
}

errorReader.close();
So it’s recommended to capture both the standard output and error output to handle both normal and abnormal cases.

 

3. Sending Input

For interactive system commands which need inputs, we can feed the inputs for the command by obtaining the OutputStream returned by the Process. For example, the following code snippet attempts to change system date on Windows to 09-20-14 (in mm-dd-yy format):

String command = "cmd /c date";

try {
	Process process = Runtime.getRuntime().exec(command);

	BufferedWriter writer = new BufferedWriter(
			new OutputStreamWriter(process.getOutputStream()));
	writer.write("09-20-14");
	writer.close();

	BufferedReader reader = new BufferedReader(new InputStreamReader(
			process.getInputStream()));
	String line;
	while ((line = reader.readLine()) != null) {
		System.out.println(line);
	}
	reader.close();
} catch (IOException e) {
	e.printStackTrace();
}
Output:

The current date is: Sat 09/20/2014
Enter the new date: (mm-dd-yy) 09-20-14
Check the system clock, it is updated immediately.

 

4. Waiting for the process to terminate

For long-running command (e.g. batch script), we can make the calling thread to wait until the process has terminated, by invoking the waitFor() method on the Process object. For example:

int exitValue = process.waitFor();
if (exitValue != 0) {
	System.out.println("Abnormal process termination");
}
 Note that the waitFor() method returns an integer value indicating whether the process terminates normally (value 0) or not. So it’s necessary to check this value.

 

5. Destroying the process and checking exit value

It’s recommend to destroy the process and checking its exit value to make sure the system command’s process is executed successfully and exited normally. For example:

process.destroy();

if (process.exitValue() != 0) {
	System.out.println("Abnormal process termination");
}
NOTE: Using the waitFor() and exitValue() method is exclusive, meaning that either one is used, not both.

 

6. Other exec() methods

Beside the primarily used method exec(Stringcommand), the Runtime class also has several overloaded ones. Notably this one:

exec(String[] cmdarray)

This method is useful to execute a command with several arguments, especially arguments contain spaces. For example, the following statements execute a Windows command to list content of the Program Files directory:

String commandArray[] = {"cmd", "/c", "dir", "C:\\Program Files"};

Process process = Runtime.getRuntime().exec(commandArray);
For other exec() methods, consult the relevant Javadoc which is listed below.

 

API References:

 

Other Java File IO Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (RunCommandExample.java)RunCommandExample.java[Java source code]4 kB

Add comment

   


Comments 

#6Pavan Kumar Bachu2019-05-14 17:10
How do I run "which" command using java ? I want to execute which appium
Quote
#5Nam2016-05-28 00:14
Quoting Dinesh:
I am unable to write to the mysql.exe after making an intial connection. and reading it. Say if i want to send a query multiple times and read the output.

So invoke exec() multiple times
Quote
#4Dinesh2016-05-26 21:01
I am unable to write to the mysql.exe after making an intial connection. and reading it. Say if i want to send a query multiple times and read the output.
Quote
#3Nam2016-01-20 01:46
Quoting Vijayadhas:
Hi.. Is it possible to show the progress in percentage? That mean I want to show some progress indicator with percentage.


I think no. You can only show the progress bar in indeterminate mode.
Quote
#2Vijayadhas2016-01-19 07:32
Hi.. Is it possible to show the progress in percentage? That mean I want to show some progress indicator with percentage.
Quote