tags:

views:

76

answers:

4

I'm trying to run a system command to extract a tar.bz2 file to a specified directory. This is the code:

ProcessBuilder myProc = new ProcessBuilder("tar", "-xjf", "/path/to/MyTarFile.tar.bz2"); 
myProc.directory(new File("/directory/i/want/results/in/"));
myProc.start();
System.out.println(myProc.command());

It runs without error, however the file is deleted and not extracted anywhere.

Any help would be greatly appreciated.

+3  A: 

Change the myProc.start(); line to

  Process p = myProc.start();
  p.waitFor();

That will make sure your program doesn't exit until the tar is finished.

Paul Tomblin
Good suggestion, however I did that and am receiving the same results.
dave
+2  A: 

Run this to see errors. Perhaps one of your paths is incorrect.

import java.io.File;
import java.io.InputStream;

public class Untar {

public static void main(String[] args) throws Exception {
    ProcessBuilder myProc = new ProcessBuilder("tar", "-xjf", "foo.tar.bz2");
    myProc.directory(new File("newdir"));
    Process p = myProc.start();
    InputStream is = p.getErrorStream();
    int c;
    while( (c = is.read()) != -1 ){
       System.out.print((char)c);
    }
    p.waitFor();
    System.out.println(myProc.command());
}

}
Dave
This will also help if stderr buffer is full. But it won't help if the stdout buffer is full.
Paul Tomblin
+4  A: 

I know Runtime.exec() has a really nasty feature where if you don't manually drain STDOUT/STDERR, it effectively appears to hang. I would hope that ProcessBuilder corrected that deficiency, but this page includes this tidbit:

A word of caution about the examples in this tip. It is possible that the examples will deadlock if the subprocess generates enough output to overflow the system. A more robust solution requires draining the process stdout and stderr in separate threads.

So, make sure you're handling Process.getInputStream() and Process.getErrorStream(), as I recommended in the comments; it could solve the problem outright!

BlairHippo
Wow, I would've never caught this. Thanks!
dave
Glad to help, mate. Got bit by this myself; completely baffling, and not fun.
BlairHippo
Alternatively, call `myProc.redirectErrorStream(true)`, which redirects standard error into standard output and gets rid of the need for a separate thread.
Pourquoi Litytestdata
... and, thanks for the warning that Runtime.exec's replacement will still force me to point those two streams at the bit bucket instead of doing it for me.
BlairHippo
A: 

Just tried this code. It works.

Check your paths.

Colin Hebert
If @BlairHippo's suggestion is correct, it might work for you and not the OP if the OP has a lot more files in his tar file than you do.
Paul Tomblin