使用Java批量下载http图像的好方法

时间:2011-05-23 22:56:08

标签: java multithreading downloading executor

我们有一个网络应用程序,需要通过http从合作伙伴网站导入10-20张图片。如果我有一个字符串列表代表我想下载的网址,那么有人建议如何尽快下载它们吗?

我可以把它们放在for循环中,但是如果有一种简单的方法可以并行化,那么最终用户可能会有所帮助。我想避免使用直接的Java线程,尽管执行程序框架可能是个好主意。

有什么想法吗?

3 个答案:

答案 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();

    }