Link to home
Start Free TrialLog in
Avatar of dech
dech

asked on

Standard Runtime.exec() and Buffer I/O question

Hi ppl,

My current code:

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("sqlplus *****/*****@***** < \"test.sql\"");
                 
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<ERROR>");
while ( (line = br.readLine()) != null)
     System.out.println(line);
System.out.println("</ERROR>");
                   
int exitVal = proc.waitFor();
// 0 for normal - nonzero for error
System.out.println("Process exitValue: " + exitVal);


I found out what is wrong with this (exec command cant take that line).

So ... now i want to

1. read in the file (test.sql) ... buffered?
2. start a new process that only does >> Process proc = rt.exec("sqlplus *****/*****@*****");
3. create an output stream for the process and dump the file text into it.

Could someone please modify my code to do something like that or suggest how i would do it.

Cheers,
Dech
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

>>Process proc = rt.exec("sqlplus *****/*****@***** < \"test.sql\"");

should be

Process proc = rt.exec("cmd.exe start /C sqlplus *****/*****@***** <test.sql");


Avatar of dech
dech

ASKER

no ... i dont think thats it
Have you tried it? As far as i can see, the only thing that will stop that from working is sqlplus not being on your PATH (oh and test.sql not being in the current directory).
Avatar of dech

ASKER

yes i have tried it ... the problem is that u cant do file redirection in exec
Avatar of dech

ASKER

section 4.6
I didn't know it can't do redirection. Problem solved then?
Avatar of dech

ASKER

no ... i cant do any of the basic stuff i said above (such as reading in a file and stuff ... so many different methods, i have no idea which is the best way).

Need your assistants
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dech

ASKER

Underneth it also says

"Nevertheless, you do not redirect the output through this approach. The incorrect assumption here is that the exec() method acts like a shell interpreter; it does not. Instead, exec() executes a single executable (a program or script). If you want to process the stream to either redirect it or pipe it into another program, you must do so programmatically, using the java.io package. Listing 4.7 properly redirects the standard output stream of the jecho process into a file."
>>The incorrect assumption here is that the exec() method acts like a shell interpreter

Not an assumption i've made ;-) cmd.exe *is* the shell interpreter, which is started by my code above:

>>java RunAsync cmd.exe start /C time "<time.txt"

And i would *guess* that redirection out will work as well, which i'll now try, attempting to redirect the output of time /T to file time.txt.

Avatar of dech

ASKER

ah ... i need this to work on both windows and unix
Actually that 'out' experiment did hang, but 'in' is fine
Please confirm the Windows version works first
To handle both Windows and Linux using exec() will involve using different commands depending on the os (check system properties to determine os).
Perhaps try writing a script/batch to perform the operation (and required redirection) and calling the batch using exec().

Alternately read the sql and perform the calls using JDBC, this would work on both platforms. Let me know if you need more details.
http://java.sun.com/docs/books/tutorial/jdbc/index.html
Avatar of dech

ASKER

                   Runtime rt = Runtime.getRuntime();
                    Process proc = rt.exec("sqlplus *****/*****@*****");
                   
                    OutputStream processStream = proc.getOutputStream();
                    PrintWriter pw = new PrintWriter(processStream);

                    InputStream stderr = proc.getErrorStream();
                    InputStreamReader esr = new InputStreamReader(stderr);
                    BufferedReader besr = new BufferedReader(esr);
                   
                    FileReader fr = new FileReader("O:\\LDN_ERS_EQUOTE\\apps\\qedbbot\\src\\com\\ubs\\equote\\qedbbot\\test.sql");  
                    BufferedReader br2 = new BufferedReader(fr);
                   
                    String currentLine = null;
                    while (br2.ready() && (currentLine = br2.readLine()) != null)
                    {
                        pw.println(currentLine);
                    }

                    String line = null;

                    System.out.println("<ERROR>");
                    while (besr.ready() && (line = besr.readLine()) != null)
                        System.out.println(line);
                    System.out.println("</ERROR>");

                    pw.close();
                    besr.close();

                    int exitVal = proc.waitFor();
                    System.out.println("Process exitValue: " + exitVal);
Avatar of dech

ASKER

Solution found ... thanks for your sugguestions ... 100 points will be awarded to CEHJ for effort
I'm 99% certain that my code will work actually. I shall ask someone else to test it. It would be easy to change the command string to get it to work on Unix.