我第一次尝试使用java期货。我有一个类来设置解压缩一些文件。想要递归解压缩,因为我有包含zip文件的zip文件。
我有一个驱动类,它实例化一个实现可调用的Uncompressor类。 Uncompressor开始解压缩,如果它遇到另一个.zip,它会创建一个自己的实例,将其添加到池中,然后继续。
伪代码
From DriverClass:
.
.
.
ExecutorService pool = new Executors.newFixedThreadPool(4);
Uncompressor uc = new Uncompressor(pool, compressedFile);
Collection<File> files = uc.uncompress();
for(Future <Collection<File>> f : uc.futures)
files.addAll(f.get());
// at the end of this loop, files doesnt seem to hold all of my files
这是我的无压缩机课程
public class Uncompressor implements Callable<Collection<File>>
{
public Set<Future<Collection<File>>> futures = new HashSet<Future<Collection<File>>>();
File compressedFile;
public Uncompressor(ExecutorService pool, File compressedFile)
{
this.pool = pool;
this.compressedFile = compressedFile;
}
public Collection<File> call() throws Exception[
return uncompress();
}
public Collection<File> uncompress()
{
List<File> uncompressedFiles = new ArrayList<File>();
.
.Loop
.//Try to uncompress the file. If the archive entry is a zip file, do the following:
Callable<Collection<File>> callable = new Uncompressor(this.pool, archiveFileEntry);
Future f = pool.submit(callable);
futures.add(f);
//else, add files to a collection here for returning
uncompressedFiles.add(archiveFileEntry);
.EndLoop
return uncompressedFiles;
.
.
}
所以问题出现在我的DriverClass中,我的文件集应该包含递归潜水中的所有未压缩文件,这里似乎并没有包含所有文件。我认为从Future获取返回值我做错了。是因为我定义了类成员变量futures
的方式吗?
谢谢
答案 0 :(得分:3)
如果您的嵌套深度大于1,您的代码将无法运行,即顶级zip包含一个包含拉链的zip。在这种情况下,您的顶级Uncompressor将无法获得底层zip文件的未来。
为此使用ForkJoinPool会很酷,因为它更适合递归类型的任务细分。 Java 7不是一个选项,我要做的是更改Uncompressor,以便结果是期货和文件的元组,然后更改调用者以跟踪所有未完成的期货:
--Caller--
Collection<File> alluncompressedFiles = new HashSet<File>();
Collection<Future<UncompressorResult>> futures = new LinkedList<Future<UncompressorResult>>();
Future<UncompressorResult> future = pool.submit(new Uncompressor(pool, compressedFile));
futures.add(future);
while (!futures.isEmpty()) {
Future<UncompressorResult> future = futures.poll();
UncompressorResult result = future.get();
futures.addAll(result.getFutures());
uncompressedFiles.addAll(result.getFiles());
}
并且Uncompressor改为:
public UncompressorResult call() throws Exception[
List<File> uncompressedFiles = new ArrayList<File>();
for (File entry : zipFiles) {
if (entry is not ZIP) {
uncompressedFiles.add(entry);
} else {
Callable<UncompressorResult> callable = new Uncompressor(this.pool, entry);
Future<UncompressorResult> f = pool.submit(callable);
futures.add(f);
}
}
return new UncompressorResult(uncompressedFiles, futures;
}