繁体   English   中英

Java进程 - 无法解压缩zip文件

[英]Java process - unable to unzip zip file

我试图解压缩一些zip文件,它有大约65兆。 代码片段如下:

此方法实际上解压缩文件:

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");
}

那个执行者/未来的东西只是为了确保我做得恰到好处。 在Finder类中调用此方法,该类在目录中找到zip文件并尝试解压缩它。 它基于此代码http://docs.oracle.com/javase/tutorial/essential/io/walk.html

所以要具体:

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
    if (find(file)) {
        synchronized(Finder.class) {
            executor.execute(file);
        }
    }
    return CONTINUE;
}

现在问题。 这真的很有趣。 每当我通过此代码提取某些内容时,zip文件实际上都会解压缩,但只有一些目录解压缩,而其他目录则不解压缩。 例如,我有一个包含目录temp foo和bar的zip文件但是在解压缩后,只有例如temp和foo目录,并且不提取bar。

这个输出是:

task added
submitted
started and waiting
shutdown

为什么没有“status = something”输出?

我不明白为什么会这样。 当我手动解压缩时,它会正确解压缩。

//编辑

这样做了

@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());
    }
}

unzip命令打印解压缩到其标准输出的文件的详细信息,因此您需要在Java程序中读取它(通过Process.getInputStream )。 如果您没有及时读取输出,则一旦缓冲区变满,进程可能会阻塞 - 这在Process的javadoc中有详细说明。

我建议您调用builder.redirectErrorStream(true) ,然后确保从流程流中读取所有数据。 您还可以从解压缩调用中添加-qq参数,以最大限度地减少它首先创建的输出量。

我认为问题是因为超时限制。

您可以尝试下面的代码来执行进程

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(commandLine);

我认为它会起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM