Java多线程下载
我是新人,要噴請輕噴
本來準備搞個java多線程下載器,在網上搜索一遍,全都是用的apache做的,我比較懶,就想如何才能不用apache搞一個出來,先搞了一個單線程的出來,用java自帶的.net包搞定,成功完成了下載,廢話不多說,下面上源碼:
?
?
/*** 完成單線程的下載任務*/ package net.meteor.download;import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection;/*** @author meteor* @email inwsy@hotmail.com* @version 1.8*/ public class Down {public static void main(String[] args) throws Exception {//給出下載地址URL url=new URL("http://codown.youdao.com/cidian/static/6.2/20140722/YoudaoDict.exe");//建立通信連接URLConnection urlcon=url.openConnection();urlcon.connect();//打開輸入流InputStream in=urlcon.getInputStream();//獲取文件String filePath=url.getFile();//返回“/”的位置索引int i=filePath.lastIndexOf("/");//得到文件名String fileName=filePath.substring(i+1);//打開輸出流,創建接收文件FileOutputStream out=new FileOutputStream("d:"+File.separator+fileName);//將文件下載到本地byte[] b=new byte[1024*1024]; int len=0;while((len=in.read(b))!=-1){out.write(b, 0, len); }} }
上面的注釋已經寫的很詳細了,我就不多解釋了,基本思想就是用URLConnection建立通信連接,然后用IO操作拿到文件,單線程的下載有了,其實變成多線程的就非常簡單了,下面上多線程代碼:
?
?
?
/*** 完成多線程下載*/ package net.meteor.download;import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL;/*** @author meteor* @email inwsy@hotmail.com* @version 1.8*/ public class MyDownload {public static String fileName;public static void main(String[] args) throws Exception {// 聲明urlURL url = new URL("http://codown.youdao.com/cidian/static/6.2/20140722/YoudaoDict.exe");//"http://pic.baomihua.com/photos/201109/m_6_634516970681718750_11187211.jpg");// 獲取鏈接HttpURLConnection con = (HttpURLConnection) url.openConnection();// 設置請求方式con.setRequestMethod("GET");// 獲取請求頭--文件長度int len = con.getContentLength();// 獲取文件長度用來計算每個線程的下載數據System.out.println("文件長度為:[ "+len+" ]");// 獲取文件String filePath = url.getFile();// 返回“/”的位置索引int i = filePath.lastIndexOf("/");// 得到文件名fileName = filePath.substring(i + 1);// 在指定目錄下創建一個同名同樣大小的文件RandomAccessFile file = new RandomAccessFile("d:" + File.separator+ fileName, "rwd");// 設置文件大小,占位file.setLength(len);// 定義線程個數int num = 10;// 計算每個線程應該下載的數據int block = len / num == 0 ? len / num : len / num + 1;System.out.println("每個線程下載的數據長度為:[ " + block+" ]");// 運行線程,并計算線程的開始字節start和結束字節endfor (int j = 0; j < num; j++) {int start = j * block;int end = start + block;System.out.println("第" + (j + 1) + "個字段 [ start:" + start + ","+ "end:" + end + "," + "block:" + block + " ]");MyDownloadThread m = new MyDownloadThread(start, end, url);Thread t = new Thread(m);t.start();}} }class MyDownloadThread implements Runnable {private int start;private int end;private URL url;InputStream in = null;RandomAccessFile out = null;public MyDownloadThread(int start, int end, URL url) {super();this.start = start;this.end = end;this.url = url;}public void run() {// 開始下載try {HttpURLConnection con = (HttpURLConnection) url.openConnection();// 設置分段下載的請求頭con.setRequestMethod("GET");con.setRequestProperty("Range", "bytes=" + start + "-" + end);// 開始下載,先判斷206if (con.getResponseCode() == 206) {// 訪問成功,則返回代碼206// 聲明輸入流in = con.getInputStream();// 聲明寫文件對象,rwd是指將數據即時的寫入到文件中,而不使用緩存區out = new RandomAccessFile("d:" + File.separator+ MyDownload.fileName, "rwd");out.seek(start);byte[] b = new byte[1024 * 1024*100];int len = 0;while ((len = in.read(b, start, end)) != -1) {out.write(b, start, len);}}} catch (Exception e) {e.printStackTrace();} finally {try {if (out != null)out.close();if (in != null)in.close();} catch (IOException e) {e.printStackTrace();}}}}?
上面url后面的兩個地址是做測試用的,圖片、exe等文件均可正常下載,出現的一個問題就是圖片下載回來會有損壞的情況,經過一番思索,認為如果在一次通信可以秒掉的情況下,下載的文件是沒有問題的,但是一次秒不掉中間會出現一些問題,為了讓程序一次秒掉下載,我后面的byte數組改的比較大,可能部分朋友在做測試的時候會炸掉虛擬機,本人是在win8.1,JDK1.8做的測試,虛擬機正常工作。關于本次編程中間出現一些問題,歡迎前來討論
?
?
上面的源代碼已經經過我重新編輯修改,找了個大神,已經把原來代碼中出現的問題解決掉了,但是又引發了新的問題,在最后讀入數據的時候為什么用read();就會出現錯誤,而改成read(byte[]?b,int?off,int?len);這個方法以后就沒有問題了,這倆方法還有什么區別么?求大神前來解答。。。
?
?
總結
- 上一篇: 查询搜狗权重用什么工具?怎样提高搜狗权重
- 下一篇: hotmail收不到邮件_将Hotmai