[英]Java process - unable to unzip zip file
I am trying to unzip some zip file, it has about 65 megs. 我试图解压缩一些zip文件,它有大约65兆。 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.
在Finder类中调用此方法,该类在目录中找到zip文件并尝试解压缩它。 It is based on this code http://docs.oracle.com/javase/tutorial/essential/io/walk.html
它基于此代码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.
每当我通过此代码提取某些内容时,zip文件实际上都会解压缩,但只有一些目录解压缩,而其他目录则不解压缩。 For example I have a zip file with directories temp foo and bar but after unzipping, there are only eg temp and foo directories and bar is not extracted.
例如,我有一个包含目录temp foo和bar的zip文件但是在解压缩后,只有例如temp和foo目录,并且不提取bar。
Output from this is: 这个输出是:
task added
submitted
started and waiting
shutdown
Why there is no "status = something" output? 为什么没有“status = something”输出?
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());
}
}
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
). unzip
命令打印解压缩到其标准输出的文件的详细信息,因此您需要在Java程序中读取它(通过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. 如果您没有及时读取输出,则一旦缓冲区变满,进程可能会阻塞 - 这在Process的javadoc中有详细说明。
I recommend you call builder.redirectErrorStream(true)
and then ensure you read all the data from the process stream. 我建议您调用
builder.redirectErrorStream(true)
,然后确保从流程流中读取所有数据。 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. 您还可以从解压缩调用中添加
-qq
参数,以最大限度地减少它首先创建的输出量。
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. 我认为它会起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.