Redirect stdin using "<" in process started w/ Runtime.exec()?

P

Paul Smith

I have 3 questions in this post that I would be most grateful for some
help with.

I want to start a process that has its input sourced from a file. I
tried:

Process process = Runtime.getRuntime().exec("c:\mysql\bin\mysql.exe
--database=bob < c:\file.sql"

but I get a usage error returned, even though running the same command
from a command prompt is fine.
The problem appears to surround the redirection of standard input
(i've tried putting a backslash in front of it).

QUESTION 1 -- Is this not possible using Runtime.exec()?

A workaround I have thought of is to pass the name of the file
containing the sql to my Java program, read it in and pass it to the
input stream of the external process. However, my application hangs
when I do this.

QUESTION 2 -- Are there any other alternatives to the workaround
below?
QUESTION 3 -- Why does the code below cause my Java program to hang?
I've seen it mentioned that the handling of the external process'
input should be on a different thread. Why is that?

The workaround code is:
try
{
OutputStream outputstream = process.getOutputStream();
OutputStreamWriter outputstreamwriter = new
OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new
BufferedWriter(outputstreamwriter);

BufferedReader br = new BufferedReader(new FileReader(fileName));
String s = br.readLine();
while (s != null)
{
bufferedwriter.write(s);
s = br.readLine();
}
bufferedwriter.flush();
}
catch (FileNotFoundException fnfe)
{
fnfe.printStackTrace();
}
 
B

bugbear

Paul said:
I have 3 questions in this post that I would be most grateful for some
help with.

I want to start a process that has its input sourced from a file. I
tried:

Process process = Runtime.getRuntime().exec("c:\mysql\bin\mysql.exe
--database=bob < c:\file.sql"

Well, those backslashes in your string aren't going to help...

BugBear
 
L

Lothar Kimmeringer

Process process = Runtime.getRuntime().exec("c:\mysql\bin\mysql.exe
--database=bob < c:\file.sql"

That can't compile, you have to escape the backslashes.
but I get a usage error returned, even though running the same command
from a command prompt is fine.

Because it's the shell's responsibility of interpreting "<" as
to read something from a file and send it to the application's
STDIN.
The problem appears to surround the redirection of standard input
(i've tried putting a backslash in front of it).

see above
QUESTION 1 -- Is this not possible using Runtime.exec()?

Of course it's possible, the only problem (despite yours) is
the different behavior of JVM on different OS, e.g. which
environment-variables are passed to the process and others.
A workaround I have thought of is to pass the name of the file
containing the sql to my Java program, read it in and pass it to the
input stream of the external process. However, my application hangs
when I do this.

If it is the code below, you fill find the answer there.
QUESTION 2 -- Are there any other alternatives to the workaround
below?

You can connect the database via JDBC and perform the statements
directly. That would make error-handling and working with the
results of e.g. selects much more convenient. AFAIR there is
a SQL-statement as well for reading in SQL-statements from a
file. That way you can come around everything concerning
the handling of external processes.
QUESTION 3 -- Why does the code below cause my Java program to hang?
I've seen it mentioned that the handling of the external process'
input should be on a different thread. Why is that?

The workaround code is:
try
{
OutputStream outputstream = process.getOutputStream();
OutputStreamWriter outputstreamwriter = new
OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new
BufferedWriter(outputstreamwriter);

BufferedReader br = new BufferedReader(new FileReader(fileName));
String s = br.readLine();
while (s != null)
{
bufferedwriter.write(s);
s = br.readLine();
}
bufferedwriter.flush();
}
catch (FileNotFoundException fnfe)
{
fnfe.printStackTrace();
}

You're not reading the output the process produces (not STDOUT
nor STDERR). The buffer for the application for writing to
STDOUT is limited. So if the application write something to
STDOUT and the buffer is already full, the write will block
until the buffer can accept more data again.

Because you're not reading the two input-streams, MYSQL automatically
will block, because the first thing happening is giving out help-
information leading to the fillup of mentioned buffer. If you want
to use process.waitFor, the reading of the two input-streams must
happen within Threads. The latter should answer question 3 as well.


Regards, Lothar
--
Lothar Kimmeringer E-Mail: (e-mail address removed)
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top