本想直接在線學(xué)習(xí),不過網(wǎng)速實在不給力,寫了個多線程下載類,把官網(wǎng)下的實例全部下載下,包括圖片,java文件,xml文件。并按照相應(yīng)目錄進(jìn)行存儲。總計時間大概6分鐘左右下完。
先貼代碼:
再貼圖:
這是http://developer.android.com/resources/samples/ApiDemos/index.html頁面下的路徑格式
下面是保存下來的文件目錄格式:
代碼直接運行即可。
先貼代碼:
package com.multilThreadDownload; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; /* * 此類是用來獲取http://developer.android.com/resources * 中的例子。 * */ public class GetFileFromWeb2 { public static final int times = 4; //請求失敗繼續(xù)請求直到成功,最多請求4次 public static final String[] imageType={"png","gif","jpg"}; //聲明可讀取的圖片類型 public static final String fileName = "index.html"; //默認(rèn)文件名 private static Map<String,String> map = new HashMap<String, String>(); //用來存儲下載失敗的文件及其地址信息 private static ArrayList<MultiThread> threadList = new ArrayList<MultiThread>(); public static void main(String[] args) { long startTime = System.currentTimeMillis(); String baseSavePath = "C:/Documents and Settings/Administrator/桌面/test/"; //寫到桌面 String basePath = "http://developer.android.com/resources/samples/ApiDemos/"; try { oneKey2GetFile(basePath,baseSavePath); } catch (Exception e) { System.out.println("網(wǎng)絡(luò)斷開或不存在此頁面:"+basePath+fileName); } while (!threadList.isEmpty()) { //確保其他線程執(zhí)行完后計算時間 System.out.println("-------"); for(int i=0;i<threadList.size();i++){ MultiThread temp = threadList.get(i); if(!temp.isAlive()){ threadList.remove(temp); } } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("下載耗時:"+(System.currentTimeMillis()-startTime)+"ms"); System.out.println("===========保存出錯列表============="); for(Map.Entry<String,String> entry:map.entrySet()){ String key = entry.getKey(); String value = entry.getValue(); System.out.println("文件名:"+key+"\t所在頁面:"+value); } } /* * 此方法用于遞歸調(diào)用 * 一鍵獲取此網(wǎng)頁文件下所有文件 * */ public static void oneKey2GetFile(String basePath,String baseSavePath)throws Exception{ String dirPath = createDir(basePath,baseSavePath); //獲取當(dāng)前創(chuàng)建的目錄 String data = null; try { data = new String(getData(basePath,fileName)); //獲取上一層目錄數(shù)據(jù) } catch (Exception e1) { throw new Exception(); } ArrayList<String> fileNames = dataFilter(data); //讀取上一層目錄數(shù)據(jù)獲取文件名 for(int i=0;i<fileNames.size();i++){ //遍歷依次讀取 String name = fileNames.get(i); System.out.println(name); if(name.endsWith("/")){ //表示是目錄 String newBasePath = basePath+name; MultiThread multi = new MultiThread(newBasePath,dirPath); threadList.add(multi); multi.start(); }else{ //表示是文件或圖片 try { byte[] files = getData(basePath,name); filterSave(files,name,dirPath); } catch (Exception e) { System.out.println(fileNames.get(i)+"讀取出錯2"); } } } } /* * 判斷獲取的文件名是否是圖片文件 * */ public static boolean containImage(String name){ for(int i=0;i<imageType.length;i++){ if(imageType[i].equals(name.substring(name.lastIndexOf('.')+1))){ return true; } } return false; } /* * 靜態(tài)方法獲取目錄名稱。并創(chuàng)建它。并返回目錄名稱 * */ public static String createDir(String path,String baseSavePath){ path = path.substring(0, path.length()-1); String dir = path.substring(path.lastIndexOf('/')+1); String dirPath = baseSavePath+dir; System.out.println("保存路徑:"+dirPath); File file = new File(dirPath); if(!file.exists()){ //創(chuàng)建目錄 file.mkdirs(); } return dirPath+"/"; } /* * 返回指定網(wǎng)頁路徑返回的數(shù)據(jù)字節(jié)流 * */ public static byte[] getData(String basePath,String fileName) throws Exception{ String fileName2 = fileName; if(!containImage(fileName)){ fileName = fileName.replaceAll("\\.\\w+", "\\.html"); } ByteArrayOutputStream byteArray =null; for (int i = 0; i < times; i++) { // 指定請求次數(shù) try { URL url = new URL(basePath + fileName); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(10 * 1000); conn.setRequestMethod("GET"); InputStream inStream = conn.getInputStream(); byte[] buff = new byte[1024]; byteArray = new ByteArrayOutputStream(); int len = 0; while ((len = inStream.read(buff)) != -1) { byteArray.write(buff, 0, len); } byteArray.flush(); byteArray.close(); inStream.close(); System.out.println(conn.getResponseCode()); if (conn.getResponseCode() == 200) break; // 如果請求成功則終止循環(huán) } catch (Exception e) { if(i>=times-1){ map.put(fileName2, basePath+GetFileFromWeb2.fileName); throw new Exception(); //請求大于指定次數(shù)后還不成功則拋出異常 } } } return byteArray.toByteArray(); } /* * 讀取上一層目錄數(shù)據(jù)獲取文件名, * 過濾文件,獲取指定的文件名數(shù)組 * */ public static ArrayList<String> dataFilter(String data){ Pattern p = Pattern.compile("<a href=\".*\">\\s*(.+/|.*\\.(xml|java|png|gif|jpg))\\s*</a>"); //匹配單個文件或目錄 Matcher matcher = p.matcher(data); ArrayList<String> fileNames = new ArrayList<String>(); while(matcher.find()){ fileNames.add(matcher.group(1)); } return fileNames; } /* * 過濾獲取指定的xml或java文件。并保存文件 * */ public static void filterSave(byte[] fileBytes,String fileName,String dirPath) throws Exception{ String fileData = new String(fileBytes); String name = dirPath + fileName; if(containImage(fileName)){ //判斷是否是圖片 FileOutputStream outStream = new FileOutputStream(name); outStream.write(fileBytes, 0, fileBytes.length); // 寫入圖片內(nèi)容 outStream.flush(); outStream.close(); }else{ fileData = fileData.replaceAll("<", "<"); fileData = fileData.replaceAll(">", ">"); /*由于存在大量的回車換行, * 需先行替換,不然匹配不出內(nèi)容, * 注意有些文件可能還含有/r,也要替換 * */ fileData = fileData.replaceAll("\n", "#@"); Pattern p = Pattern.compile("<pre>(.*)</pre>"); Matcher matcher = p.matcher(fileData); while(matcher.find()){ String str = matcher.group(1).replaceAll("#@", "\n"); //匹配到后再替換回來 File file = new File(name); FileWriter writer = new FileWriter(file); writer.write(str, 0, str.length()); writer.flush(); writer.close(); } } System.out.println(name); } static class MultiThread extends Thread{ private String basePath; private String baseSavePath; public MultiThread(){ } public MultiThread(String basePath,String baseSavePath){ this.basePath = basePath; this.baseSavePath = baseSavePath; } @Override public void run(){ try { oneKey2GetFile(basePath,baseSavePath); } catch (Exception e) { System.out.println("讀取目錄:"+basePath+" 出錯"); } } } }
再貼圖:
這是http://developer.android.com/resources/samples/ApiDemos/index.html頁面下的路徑格式

下面是保存下來的文件目錄格式:

代碼直接運行即可。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
