2011-05-23 41 views
5

我們有一個web應用程序需要通過http從合作伙伴網站導入10-20張圖片。如果我有一串代表我想下載的網址的字符串列表,是否有人會建議如何儘快下載它們?用Java通過http批量下載圖像的好方法

我可以把它們放在一個for循環中,但如果有一種簡單的方法來並行化它,它可能會對最終用戶有好處。我想避免使用直接的Java線程,儘管執行器框架可能是一個好主意。

任何想法?

回答

1

Executor框架完全是你想要的。特別是ExecutorCompletionService。使用此功能,您可以快速以任意順序提交請求。然後,您將完整地檢索它們(而不是提交順序)。

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

} 
+0

是可能的,如果我不想改變形象的名字可以下載?我想要使​​用與URL中相同的名稱。 – 2012-11-01 23:39:51

0

使用Resty庫的圖像可以自定義名稱如下

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

    }