스레드는 다운로드 채널로 이해할 수 있습니다. 하나의 스레드는 파일 다운로드 채널입니다. 여러 스레드는 여러 다운로드 채널을 동시에 열 수 있음을 의미합니다. 서버가 다운로드 서비스를 제공하면 사용자 다운로더는 대역폭을 공유합니다. 우선 순위가 동일하면 총 서버는 총 다운로드 스레드를 고르게 할당합니다. 이해하기 어렵지 않습니다. 스레드가 많으면 다운로드가 빨라집니다.
인기있는 다운로드 소프트웨어는 멀티 스레딩을 지원하고 중간 정지 일시 정지 다운로드를 지원합니다. 다시 시작하면 처음부터 다운로드하지 않습니다.
두 기능을 구현하는 단계는 다음과 같습니다.
(1) 다운로드 리소스 파일에 연결할 때 먼저 리소스 파일의 크기를 결정하고 로컬로 동일한 크기의 임시 파일을 만들어 다운로드 데이터를 저장하십시오.
(2) 스레드 수에 따라 각 스레드에 필요한 파일 크기 결정
(3) 각 스레드에서 다운로드 한 파일 크기 및 스레드 수에 따라 각 스레드의 시작 및 종료 다운로드 위치를 결정하고 각 스레드에서 다운로드 한 파일 크기 및 스레드 수에 따라 각 스레드의 시작 및 종료 다운로드 위치를 결정하십시오.
(4) 브레이크 포인트 다운로드 기능을 실현하기 위해서는 다음에 처음부터 진행된 다운로드를 용이하게하기 위해 각 스레드의 실시간 다운로드 위치를 표시해야합니다.
오픈 3 스레드 다운로드보기 (기본 다운로드 디렉토리는 Java의 프로젝트입니다) :
전체 구현 코드는 다음과 같습니다.
import java.io.bufferedReader; import java.io.file; import java.io.fileInputStream; import java.io.inputStreamReader; import java.io.randomaccessfile; import java.net.httpurlConnection; httpurlConnection; vormation java.net.url; public download {// 다운로드 2 "red aler"reder "reder" 문자열 path = "http://soft3.xzstatic.com/2015/10/hsjj2ghgzh.rar"; public static int strookcount = 0; // 스레드 수를 선언 공개 static void main (String [] args) {try {url url = new url (path); // 연결을 가져옵니다 httpurlConnection conn = (httpurlConnection) url.openConnection (); // 연결 문자열을 가져 와서 파일 이름을 정의합니다 [] str = path.split ( "/"); 문자열 filename = str [5]; // 다운로드 파일 크기를 가져옵니다. int FileLength = conn.getContentLength (); System.out.println (filename); // 서버 크기와 일치하는 무작위로 작성된 파일을 생성 로컬 randomAccessFile RAF = 새로운 RandomAccessFile (Filename, "RWD"); System.out.println (filelength); // test raf.setlength (filelength); // 사용자 정의 스레드 카운트 threadCount = 3; // 각 스레드에서 다운로드 한 데이터 크기를 계산 int blocksize = filelength / strookcount; // (int strandid = 1; threadId <= threadCount; threadId ++) {// core 코드, 각 스레드가 시작되고 끝나는 다운로드 위치를 정의합니다. 각 스레드가 시작되고 끝나는 다운로드 위치를 정의합니다. 길이; } 새 스레드 (new DownloadLoadThread (ThreadId, StartPos, Endpos, Path)) .start (); }} catch (예외 e) {e.printstacktrace (); }} // 다운로드 스레드 정적 클래스 다운로드 다운로드로드 리드는 runnable {private int threadid; 개인 int startpos; 개인 int endpos; 개인 문자열 경로; public downloadLoadTheRDRED (int strandid, int startpos, int endpos, 문자열 경로) {super (); this.threadid = threadid; this.startpos = startpos; this.endpos = endpos; this.path = 경로; } public void run () {try {url url = new url (Path); 문자열 [] str = path.split ( "/"); 문자열 filename = str [5]; httpurlconnection conn = (httpurlConnection) url .openConnection (); // URL 요청 방법을 설정합니다 (자세한 내용은 API 참조) Conn.setRequestMethod ( "get"); // 시간 초과 값으로 500ms를 설정합니다 Conn.SetReadTimeout (5000); 파일 = 새 파일 (threadid + ".txt"); if (file.exists () && file.length ()> 0) {bufferedReader br = new bufferedReader (new inputStreamReader (new FileInputStream (file))); 문자열 savestartpos = br.readline (); if (savestpos! = null && savestartpos.length ()> 0) {startpos = integer.parseint (savestartpos); }} // 이중 인용문으로 형식에주의를 기울이고 공백 (예 : 다른 문자)을 포함 할 수 없으며, 그렇지 않으면 416 이보고됩니다. conn.setRequestProperty ( "범위", "bytes =" + startpos + "-" + endpos); RandomAccessFile RAF = 새로운 RandomAccessFile (filename, "rwd"); // 랜덤 쓰기 파일을 다운로드 파일 raf.seek (startpos)에 저장; // 다운로드 System.out.println ( "스레드" + 스레드 + ":" + startpos + "~~" + endpos); inputStream은 = conn.getInputStream (); 바이트 [] B = 새로운 바이트 [1024 * 1024 * 10]; int len = -1; int newpos = startpos; while ((len = is.read (b))! = -1) {randomaccessfile rr = new randomaccessfile (파일, "rwd"); // 다운로드 태그 raf.write (b, 0, len)를 저장하는 파일; // 지정된 문서에 다운로드 태그를 저장 string savapoint = string.valueof (newpos += len); rr.write (savapoint.getBytes ()); rr.close (); } is.close (); raf.close (); System.out.println ( "완료 다운로드"); } catch (예외 e) {e.printstacktrace (); }}}}참고 :
(1) 각 스레드 다운로드의 시작 및 종료 위치의 계산 방법을 이해합니다 (마지막 스레드 포함, 0부터 시작).
시작 위치 = (스레드 수 -1) * 각 스레드에서 다운로드 할 파일의 길이 (크기)
종료 위치 = (스레드 번호 * 각 스레드에서 다운로드 한 파일 크기) -1
(2) 마지막 스레드에 의해 할당 된 다운로드 시작 위치는 이전 스레드의 끝 위치이며, 끝 위치는 파일 길이입니다.
따라서 마지막 스레드에서 다운로드 한 파일 길이는 일반적으로 이전 스레드와 같지 않습니다.
(3)이 데모의 다운로드 경로는 Java 프로젝트가 기본적으로 위치한 디렉토리이며, 디렉토리는 다운로드 된 파일과 동일한 이름의 파일을 포함 할 수 없으며, 그렇지 않으면 프로그램이 416 네트워크 요청 오류를보고합니다.
(4) Conn.SetRequestProperty ( "범위", "bytes ="+startpos+"-"+endpos); 인용문에는 반드시 여분의 공간과 다른 캐릭터가있는 것은 아닙니다. 나는 인용문에 공간이 있지만 오류 포지셔닝은 항상 입력 스트림 오류였으며 잘못된 오류를 찾는 것은 매우 고통 스럽습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.