Reputation: 1322
I am trying to unzip some zip file, it has about 65 megs. Code snippets below:
This method actually unzips a file:
public synchronized void execute(Path zipFile) {
final ProcessBuilder builder = new ProcessBuilder("/bin/unzip",zipFile.toAbsolutePath().toString(), "-d", dir.toAbsolutePath().toString());
FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
@Override public Integer call() {
try {
System.out.println("started and waiting");
int status = builder.start().waitFor();
System.out.println("status: " + status);
return status;
} catch (InterruptedException e) {
} catch (IOException e) {
}
return 0;
}
});
List<FutureTask<Integer>> tasks = new ArrayList<FutureTask<Integer>>();
tasks.add(task);
System.out.println("task added");
ExecutorService executor = Executors.newCachedThreadPool();
for (FutureTask<Integer> t : tasks) {
executor.submit(t);
System.out.println("submitted");
}
executor.shutdown();
System.out.println("shutdown");
}
That executor / future stuff is there just to be sure I do it properly. This method is called in the class Finder, which finds zip file in the directory and tries to unzip it. It is based on this code http://docs.oracle.com/javase/tutorial/essential/io/walk.html
So to be concrete:
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (find(file)) {
synchronized(Finder.class) {
executor.execute(file);
}
}
return CONTINUE;
}
Now the problem. It is really funny. Whenever I extract something by this code, the zip file actually gets unzipped but ONLY some directories are unzipped and others are not. For example I have a zip file with directories temp foo and bar but after unzipping, there are only e.g temp and foo directories and bar is not extracted.
Output from this is:
task added
submitted
started and waiting
shutdown
Why there is no "status = something" output?
I can't understand why it is so. When I unzip it manually, it gets unzipped properly.
// EDIT
this did the trick
@Override
public synchronized void execute(String file, String dest) {
ProcessBuilder pb = new ProcessBuilder("/bin/unzip","-qq", file, "-d", dest);
pb.redirectErrorStream(true);
try {
Process p = pb.start();
InputStream is = p.getInputStream();
InputStreamReader r = new InputStreamReader(is);
BufferedReader in = new BufferedReader(r);
String line;
while ((line = in.readLine()) != null) {
// because of the -qq option, it does actually write out nothing
System.out.println(line);
}
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
Upvotes: 1
Views: 2628
Reputation: 122364
The unzip
command prints the details of the files it is unzipping to its standard output, so you need to read this in your Java program (via Process.getInputStream
). If you don't read the output in a timely fashion the process may block once its buffer gets full - this is spelled out in the javadoc of Process.
I recommend you call builder.redirectErrorStream(true)
and then ensure you read all the data from the process stream. You may also benefit from adding a -qq
argument to the unzip call, to minimise the amount of output it creates in the first place.
Upvotes: 2
Reputation: 1
I think problem is because of timeout constraint.
You can try below code to execute process
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(commandLine);
I think it will work.
Upvotes: 0