stewenson
stewenson

Reputation: 1322

Java process - unable to unzip zip file

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

Answers (2)

Ian Roberts
Ian Roberts

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

shekhar
shekhar

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

Related Questions