Redirect a System Process into Java Application for Windows and Linux

The output or input redirection is often used by the command line script guys. The output redirection (“>”) is usually to the file instead of the standard output. The input redirection (“<”) is to have a file as input instead of the standard input. It is sometimes needed in the programs too.

Interoperability with other programs is another concept especially when developing interoperable application. To do that the programming framework often sports different libraries for interoperability. However sometimes, for a simple code you don’t want to call the low level heavy libraries for doing the operation while there is a simple workaround.

There might be three ways of doing it.

  1. Trusting to the environment shell or command prompt.
  2. Use the Java internal process libraries and do the redirection ourselves.
  3. Use JNI class libraries for doing cross platform operation with the native code.

In one of the projects I was working with one of the earthquake modules that does some calculations. The program is in compiled form that it won’t worth the reimplementation. Instead I needed to call from the environment and display the output.

In order to use the system command prompt it is needed to use the “exec” method of the Runtime. This solution might not be guaranteed to work if the command line is broken or it is not with the standard names. Also it is not really beautiful to have if statements detecting the operating system and behaving on that.

Runtime.getRuntime().exec(cmdCommand);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void creatproc()
{
	String osName = System.getProperty("os.name");
	Process p;

	if (osName.startsWith("Windows"))
	{
		String cmdwin = "cmd /c C:EWv6.2binhyp2000.exe < C:EWv6.2bininput.txt";
		try
		{
			File f = new File("C:EWv6.2bin");
			Runtime.getRuntime().exec(cmdwin, null, f);
		}
		catch (IOException e)
		{

			e.printStackTrace();
		}
	}
	else
	{
		String[] cmdlinux = new String[3];
		cmdlinux[0] = "/bin/sh";
		cmdlinux[1] = "-c";
		cmdlinux[2] = "hypo2000 < input.txt";
		try
		{
			Runtime.getRuntime().exec(cmdlinux);
		}
		catch (IOException e)
		{

			e.printStackTrace();
		}
	}
}

After detecting the operating system it for windows it is needed to call cmd and for Linux> it is needed to call sh. There is one implementation between the command prompt of those operating systems as well. Likewise Windows could tell the difference of a single string while in Linux you have to specify the command arguments as the arrays of string. Other than that everything works exactly the same as you would expect.

A better implementation would be to use the java.io.BufferedReader; and feed the process that we have opened with the file contents. It is like implementing the behind scenes in our Java code. We create the process and write to the process output while reading from the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public void Redirect()
{
	BufferedReader freader = null;
	PrintStream fout = null;
	java.io.PipedReader pRead = null;
	PipedOutputStream po = null;
	Process p = null;
	try
	{
		freader = new BufferedReader(new FileReader("C:EWv6.2bininput.txt"));

	}
	catch (FileNotFoundException e1)
	{

		e1.printStackTrace();
	}
	try
	{
		File f = new File("C:EWv6.2bin");

		p = Runtime.getRuntime().exec("C:EWv6.2binhyp2000.exe",
				null, f);
		fout = new PrintStream(p.getOutputStream());
	}
	catch (IOException e)
	{

		e.printStackTrace();
	}
	String line = "";
	try
	{
		while ((line = freader.readLine()) != null)
		{
			fout.println(line);
		}
		fout.flush();
	}
	catch (IOException e1)
	{

		e1.printStackTrace();
	}
	try
	{
		p.waitFor();
	}
	catch (InterruptedException e)
	{

		e.printStackTrace();
	}
}

I found the usage of Java process libraries better than the others, but for quick solution the others might be helpful as well. Also it doesn’t look good in terms of “portability” of the application code.