我们有一个网络应用程序,需要通过http从合作伙伴网站导入10-20张图片。如果我有一个字符串列表代表我想下载的网址,那么有人建议如何尽快下载它们吗?
我可以把它们放在for循环中,但是如果有一种简单的方法可以并行化,那么最终用户可能会有所帮助。我想避免使用直接的Java线程,尽管执行程序框架可能是个好主意。
有什么想法吗?
答案 0 :(得分:5)
以下是我使用Resty的观点。 (免责声明:我是Resty的作者) 下载命令行中给出的所有URL并打印出文件名。
package us.monoid.web.parallel;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import us.monoid.web.Resty;
public class Downloader {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Callable<File>> tasks = new ArrayList<Callable<File>>(args.length);
for (final String url : args) {
tasks.add(new Callable<File>() {
public File call() throws Exception {
return new Resty().bytes(url).save(File.createTempFile("img", ".png"));
}
});
}
List<Future<File>> results = pool.invokeAll(tasks);
for (Future<File> ff : results) {
System.out.println(ff.get());
}
}
}
答案 1 :(得分:1)
Executor框架完全符合您的要求。特别是ExecutorCompletionService。使用此功能,您将能够以任何顺序快速提交请求。然后,您将完全按照完成时检索它们(而不是提交订单)。
答案 2 :(得分:0)
使用Resty Library图像可以使用自定义名称下载,如下所示
try {
ExecutorService pool = Executors.newFixedThreadPool(Names.size());
List<Callable<File>> tasks = new ArrayList<Callable<File>>(Names.size());
for (final String url : Urls) {
tasks.add(new Callable<File>() {
public File call() throws Exception {
File f=new File(directory+iimage);
return new Resty().bytes(url).save(f);
}
});
i++;
}
i=0;
List<Future<File>> results = pool.invokeAll(tasks);
for (Future<File> ff : results) {
System.out.println(ff.get());
}
} catch (ExecutionException e) {
// TODO Auto-generated catch block
fails++;
e.printStackTrace();
}