Problem invoking Windows copy command using Runtime.getRuntime().exec()

D

Dave Neuendorf

I'm trying to use Runtime.exec to execute the Windows XP copy command,
to back up a file to another location on the same hard drive. Here is
the code I'm using to do this (where backupDirectory is a File instance
for the directory where I want to store the copy):

String dest = backupDirectory.getAbsolutePath() + "\\" +
DATABASE_FILE_NAME;
String sourceFile = DATABASE_PATH + "\\" + DATABASE_FILE_NAME;
String[] command = { "cmd.exe", "copy", sourceFile, dest };
Runtime.getRuntime().exec( command );

This does not throw any exceptions, but the copy is not made. If I call
waitFor() on the Process returned by exec(), and put the code in a
try/finally structure, the code in the finally never gets executed, so
it looks like it never gets past the waitFor().

I would appreciate any help.

Thanks,
Dave Neuendorf
 
K

klynn47

After the "cmd.exe" try adding "/c".

If that still doesn't work, then you can get a reference to the
ErrorStream of the Process with getErrorStream(). Then you can read
from it with a BufferedReader.
 
O

Oscar kind

Dave Neuendorf said:
I'm trying to use Runtime.exec to execute the Windows XP copy command,
to back up a file to another location on the same hard drive. Here is
the code I'm using to do this (where backupDirectory is a File instance
for the directory where I want to store the copy):

Why can you not create the copy yourself? It can be almost this simple
(just add exception handling, and maybe buffering):

File sourceFile = null; // Initialize these correctly
File destFile = null;

InputStream input = new FileInputStream(sourceFile);
OutputStream output = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int bytesRead = 0;
do {
output.write(buffer, 0, bytesRead); // Writes nothing the first pass.
bytesRead = input.read(buffer);
} while (bytesRead >= 0);
 
W

Wiseguy

Oscar kind said:
Dave Neuendorf said:
I'm trying to use Runtime.exec to execute the Windows XP copy command,
to back up a file to another location on the same hard drive. Here is
the code I'm using to do this (where backupDirectory is a File instance
for the directory where I want to store the copy):

Why can you not create the copy yourself? It can be almost this simple
(just add exception handling, and maybe buffering):

File sourceFile = null; // Initialize these correctly
File destFile = null;

InputStream input = new FileInputStream(sourceFile);
OutputStream output = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int bytesRead = 0;
do {
output.write(buffer, 0, bytesRead); // Writes nothing the first pass.
bytesRead = input.read(buffer);
} while (bytesRead >= 0);

While this is certainly a valid solution, it is often more efficient to
call the native function of the OS platform in question for such functions.
The reason is that even with bufferring, copying in java, or any userspace
program, may be slower than using the native OS command.

An example of this is the cp command in Unix that copies files and directories.
The cp command uses a system level (file memory mapping) mechanism that is
much faster than copying a file in a user space process.

The caveat to my solution is that the process then becomes OS specific.
 
D

Dave Neuendorf

The "/c" did the trick! Thanks for the quick help.

Regarding the other proposed solution of rolling my own copy routine, I
wanted to avoid that because this backup is sneaking itself in when the
app isn't busy, and I want it to happen as fast as possible (the
software is semi "real time," used to control a machine in a factory).
Using the OS facility is probably the best way to ensure that.
 
A

Anthony Borla

Dave Neuendorf said:
The "/c" did the trick! Thanks for the quick help.

Regarding the other proposed solution of rolling my own
copy routine, I wanted to avoid that because this backup
is sneaking itself in when the app isn't busy, and I want it
to happen as fast as possible (the software is semi "real
time," used to control a machine in a factory). Using the
OS facility is probably the best way to ensure that.

Ah, no, it isn't the *best* way of ensuring that the task is completed in
the shortest time possible simply because using an OS command involves the
creation of a new process, and there is *always* a time penalty [as well as
other overhead] involved in this task The relative time penalty does,
however, vary with the host operating system: process creation on *NIX
systems is generally cheap, it is more expensive on Windows-family systems,
and significantly more expensive on 'large system' OS like OpenVMS, and
IBM's MVS-family OS's [though there are other benefits to be had from this
overhead].

If you need to perform a task within fairly tight time constraints then a
JNI routine is probably the most appropriate solution since there is no
process creation penalty / overhead, and the code can be optimised to the
specific task.

An alternative, though obviously more complex, approach may be to use a
separate worker process to which task requests are sent; the worker process
simply receives, queues, and dispatches the task requests. This approach
might be useful where many different types of tasks need to be performed. By
the by, a separate worker thread approach could also be used: there wouldn't
even be any request dispatch latency.

Cheers,

Anthony Borla
 

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

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top