本文介绍了Java 进程 - 无法解压缩 zip 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解压缩一些 zip 文件,它大约有 65 兆字节.以下代码片段:

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

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

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

所以要具体:

@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 未提取.

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.

由此产生的输出是:

task added
submitted
started and waiting
shutdown

为什么没有status = something"输出?

Why there is no "status = something" output?

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

I can't understand why it is so. When I unzip it manually, it gets unzipped properly.

//编辑

这成功了

@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 中有详细说明.

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.

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

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.

这篇关于Java 进程 - 无法解压缩 zip 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 08:48
查看更多