日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

仿迅雷下载项目分析

發(fā)布時間:2023/12/14 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 仿迅雷下载项目分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一,下載項目分析:

1,單線程下載:網(wǎng)絡(luò) 流2,多線程下載a,每個線程下載多少數(shù)據(jù)。 文件總大小%線程數(shù)==0? 文件總大小%線程數(shù):文件總大小/線程數(shù)+1;b,某個請從資源 的某個位置下載 => http協(xié)議請求頭 Range: byte=xxx-xxc,在下載前,取出要下載的文件的大小,并在本地建立一個同大小的文件。RanddomAccessFilesetFileSize();d,如何讓線程找到文件的指定位置寫入RanddomAccessFileseek(int position) 3,斷點續(xù)傳a,將沒下完的文件記錄到 屬性文件/XML文件4,迅雷最新的技術(shù);多服務(wù)器下載,從不同的服務(wù)器找到文件源進(jìn)行下載。 vip客戶這個項目主要是實現(xiàn)了第2個方案:XunleiTest類:這個是測試類,設(shè)置了參數(shù):URL: 下載的目的地址threadCount: 線程數(shù)DownLoadManager: 創(chuàng)建的下載管理類然后調(diào)用其download()方法:值得一提的是在調(diào)用這個方法時,同時實現(xiàn)了OnSizeChanged接口這個接口是用來實時顯示已經(jīng)下載了多少數(shù)據(jù),即進(jìn)度是多少,采用的是回調(diào)函數(shù)的形式。里面是靠total不斷的累加得到的數(shù)據(jù)和,這個total要定義成全局靜態(tài)的,要不就達(dá)不到數(shù)據(jù)變化的效果DownLoadManager類:download()方法:參數(shù)說明 url:要下載的文件的url threadCount :線程數(shù) Directory:保存的目錄位置 OnSizeChanged:下載的數(shù)據(jù)量1,取出文件大小 getFileSize(url):A,通過 openConnection()建立連接B,注意:在此方法中因為只需要知道獲得文件的大小,所以setRequestMethod()設(shè)置為HEADC,getResponseCode()獲取服務(wù)器的響應(yīng)碼要是為200,則表示訪問成功D,getContentLength()接受其文件的大小2, 將下載的文件重新命名 genFileName():A,取到當(dāng)前的時間到秒B,通過url.getFile()取到下載的文件的名字,通過截取的方式保留文件的后綴名3,創(chuàng)建文件:gen():用來創(chuàng)建一個新的文件帶保存地址和名字如果有保存的地址則如果有保存的地址則用有的,如果沒有則通過System.getProperty("user.dir");用系統(tǒng)默認(rèn)的。createSaveFile():用來在劃分一個空間,用來以后接受下載時接受數(shù)據(jù);//RandomAccessFile:此類的實例支持對隨機(jī)訪問文件的讀取和寫入.隨機(jī)訪問文件的行為類似存儲在文件系統(tǒng)中的一個大型 byte 數(shù)組//"rwd" 打開以便讀取和寫入,對于 "rw",還要求對文件內(nèi)容的每個更新都同步寫入到底層存儲設(shè)備。RandomAccessFile raf=new RandomAccessFile(saveFile, "rwd");4:每個線程需要下載的長度 getSizePerThread();文件總大小%線程數(shù)==0? 文件總大小%線程數(shù):文件總大小/線程數(shù)+15,根據(jù)線程數(shù)threadCount啟動線程 DownLoadService并將這些參數(shù)傳過去:URL:下載地址i: 當(dāng)前線程sizePerThread:該線程要下載的長度savefile:保存的文件onSizeChanged:下載的變化量DownLoadService類是一個實現(xiàn)了Runnable接口的一個類:run():A,計算當(dāng)前的線程的起始位置 startB,計算當(dāng)前的線程的終點位置 endC,建立與資源的連接:這里的setRequestMethod()用"GET",因為要正式下載其內(nèi)容了注意:需要設(shè)置下載時的長度//設(shè)置一般請求屬性 鍵 值setRequestProperty("Range", "bytes="+start+"-"+end)//HTPP屬性: Range 字節(jié)范圍D,用字節(jié)輸入流接受數(shù)據(jù) InputStreamE,創(chuàng)建RandomAccessFile注意:為了能點對點的將數(shù)據(jù)精確插入這里使用了RandomAccessFile.seek(start);F,進(jìn)入循環(huán)將流寫到本地,并且其實回傳onSizeChanged即顯示的進(jìn)度量

具體代碼:

package com.yc.bean3.xunleixaizai;

import java.io.IOException;

import java.net.URL;

public class XunleiTest {

static long total=0; /*** @param args* @throws IOException */ public static void main(String[] args) throws IOException {URL url=new URL("http://yze.t.sogou.com/installpage/sogougmoh.e?dn=ThunderSpeed_1.0.32.350_XiaZaiBa_sgdl.exe");int threadCount=4;DownLoadManager dlm=new DownLoadManager();dlm.download(url, threadCount, null, new OnSizeChanged(){@Overridepublic void nofiySizeChange(long size) {total+=size;System.out.println("已經(jīng)下載了:"+total+"字節(jié)");}}); }

}

package com.yc.bean3.xunleixaizai;

public interface OnSizeChanged {

public void nofiySizeChange(long size);

}

package com.yc.bean3.xunleixaizai;

import java.io.File;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DownLoadManager {
//下載方法: url:要下載的文件的url threadCount :線程數(shù) Directory:保存的目錄位置
public void download(URL url,int threadCount,File Directory, OnSizeChanged onSizeChanged) throws IOException{
long filesize=-1;

try {//1取出文件大小filesize=getFileSize(url);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//2,取出文件名String filename=genFileName(url);//3創(chuàng)建文件File savefile=gen(filename, Directory);createSaveFile(savefile, filesize);//求出每個線程要下載的長度long sizePerThread=getSizePerThread(filesize, threadCount);//4根據(jù) 線程數(shù)據(jù)啟動線程for(int i=0;i<threadCount;i++){Thread t=new Thread(new DownLoadService(url,i,sizePerThread,savefile,onSizeChanged));t.start();}}//求出每個線程要下載的文件長度 private long getSizePerThread(long filesize,int threadCount){return filesize%threadCount==0? filesize/threadCount: filesize/threadCount+1; }//獲取要下載的文件大小 private long getFileSize(URL url) throws IOException{long filesize=-1;HttpURLConnection con = (HttpURLConnection) url.openConnection();con.setConnectTimeout(40000); //保持與服務(wù)器的連接的時間con.setRequestMethod("HEAD");//注意:請求方式不同,返回的流的數(shù)據(jù)不同con.connect();int code=con.getResponseCode(); //獲取服務(wù)器的響應(yīng)碼if(code==200){filesize=con.getContentLength();}return filesize; }//在磁盤上創(chuàng)建保存文件 //saveFile:要保存的文件的全路徑 //filesize:文件的大小 private void createSaveFile(File saveFile,long filesize) throws IOException{//RandomAccessFile:此類的實例支持對隨機(jī)訪問文件的讀取和寫入. 隨機(jī)訪問文件的行為類似存儲在文件系統(tǒng)中的一個大型 byte 數(shù)組//"rwd" 打開以便讀取和寫入,對于 "rw",還要求對文件內(nèi)容的每個更新都同步寫入到底層存儲設(shè)備。 RandomAccessFile raf=new RandomAccessFile(saveFile, "rwd");raf.setLength(filesize);raf.close(); }//savefilename:要保存的文件名 //savedirectory: 要保存的目錄,如果為空的話,則系統(tǒng)指定目錄 private static File gen(String savefilename, File savedirectory) {File f=null;if(savedirectory==null){f=new File(System.getProperty("user.dir"),savefilename);}else{f=new File(savedirectory,savefilename);}return f; }//從url中取后綴名 : yyyyMMddHHmmss.原文件的后綴名 private static String genFileName(URL url){Date d=new Date();SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");String filename=sdf.format(d);//從url中取后綴名String suffix=url.getFile().substring(url.getFile().lastIndexOf("."));filename+=suffix;return filename;}

}

package com.yc.bean3.xunleixaizai;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;

public class DownLoadService implements Runnable {
private URL url;
private int i;
private long sizePerThread;
private File savefile;
private boolean flag;
private OnSizeChanged onSizeChanged;

public DownLoadService(URL url,int i, long sizePerThread,File savefile, OnSizeChanged onSizeChanged){super();this.url=url;this.i=i;this.sizePerThread=sizePerThread;this.savefile=savefile;flag=true;this.onSizeChanged=onSizeChanged; }@Override public void run() {//4計算當(dāng)前的線程的起始位置long start=i*sizePerThread;//5計算當(dāng)前的線程的終點位置long end=(i+1)*sizePerThread-1;InputStream iis=null;//1,建立與資源的連接HttpURLConnection con;try {con = (HttpURLConnection) url.openConnection();con.setConnectTimeout(40000); //保持與服務(wù)器的連接的時間con.setRequestMethod("GET");//注意:請求方式不同,返回的流的數(shù)據(jù)不同con.setRequestProperty("Range", "bytes="+start+"-"+end);con.connect();iis=con.getInputStream();} catch (ProtocolException e2) {// TODO Auto-generated catch blocke2.printStackTrace();} catch (IOException e2) {// TODO Auto-generated catch blocke2.printStackTrace();}//2創(chuàng)建輸入流//3創(chuàng)建RandomAccessFile//RandomAccessFile:此類的實例支持對隨機(jī)訪問文件的讀取和寫入. 隨機(jī)訪問文件的行為類似存儲在文件系統(tǒng)中的一個大型 byte 數(shù)組//"rwd" 打開以便讀取和寫入,對于 "rw",還要求對文件內(nèi)容的每個更新都同步寫入到底層存儲設(shè)備。 RandomAccessFile raf = null;try {raf = new RandomAccessFile(savefile, "rwd");//給raf定位raf.seek(start);//設(shè)置到此文件開頭測量到的文件指針偏移量,在該位置發(fā)生下一個讀取或?qū)懭氩僮鱹 catch (Exception e2) {e2.printStackTrace();}while(flag){byte[] bs=new byte[1024];int length=-1;try {while((length=iis.read(bs,0,bs.length))!=-1){raf.write(bs,0,length);if(this.onSizeChanged!=null){this.onSizeChanged.nofiySizeChange(length);}}flag=false;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} }

}

總結(jié)

以上是生活随笔為你收集整理的仿迅雷下载项目分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。