자바 다 중 스 레 드 정지점 에서 인 스 턴 스 코드 다운로드(다운로드 중 일시 정지 가능)

스 레 드 는 다운로드 채널 로 이해 할 수 있 습 니 다.하나의 스 레 드 는 파일 의 다운로드 채널 입 니 다.다 중 스 레 드 는 여러 개의 다운로드 채널 을 동시에 여 는 것 입 니 다.서버 가 다운로드 서 비 스 를 제공 할 때 다운로드 자 는 공유 대역 폭 이 며,우선 순위 가 같은 경우 총 서버 는 총 다운로드 스 레 드 를 평균 적 으로 배정 합 니 다.이해 하기 어렵 지 않 습 니 다.스 레 드 가 많 으 면 다운로드 가 빠 릅 니 다.
현재 유행 하 는 다운로드 소프트웨어 는 다 중 스 레 드 를 지원 하고 중간 에 다운 로드 를 중단 하 는 것 을 지원 하 며 다시 시작 할 때 처음부터 다운로드 하지 않 습 니 다.
두 가지 기능 의 실현 절 차 는 다음 과 같다.
(1)다운로드 자원 파일 에 연결 할 때 먼저 자원 파일 의 크기 를 판단 하고 로 컬 에서 같은 크기 의 임시 파일 을 만들어 다운로드 데 이 터 를 저장 합 니 다.
(2)스 레 드 수량 에 따라 스 레 드 마다 다운로드 할 파일 크기 확인
(3)각 스 레 드 에서 다운로드 한 파일 의 크기 와 스 레 드 수량 에 따라 각 스 레 드 의 시작 다운로드 위치 와 다운로드 종료 위 치 를 결정 합 니 다.
(4)인 터 럽 트 다운로드 기능 을 실현 하기 위해 서 는 각 스 레 드 가 실시 간 으로 다운로드 하 는 위 치 를 표시 하여 다음 에 시작 할 때 까지 진 도 를 계속 다운로드 할 수 있 도록 해 야 한다.
3 개의 스 레 드 다운로드 보 기 를 엽 니 다(기본 다운로드 디 렉 터 리 는 자바 가 관할 하 는 항목 입 니 다).

전체적인 실현 코드 는 다음 과 같다.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownLoad {
  //       “    2”
  public static final String PATH = "http://soft3.xzstatic.com/2015/10/hsjj2ghgzh.rar";
  public static int threadCount = 0;//       
  public static void main(String[] args) {
    try {
      URL url = new URL(PATH);
      //     
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      //            
      String[] str = PATH.split("/");
      String fileName = str[5];
      //         
      int fileLength = conn.getContentLength();
      System.out.println(fileName);
      //                        
      RandomAccessFile raf = new RandomAccessFile(fileName, "rwd");
      System.out.println(fileLength);//    
      raf.setLength(fileLength);
      //        
      threadCount = 3;
      //              
      int blockSize = fileLength / threadCount;
      //       
      for (int threadId = 1; threadId <= threadCount; threadId++) {
        //     ,                 
        int startPos = (threadId - 1) * blockSize;//        
        int endPos = (threadId * blockSize) - 1;//        (       )
        if (threadCount == threadId) {
          endPos = fileLength;
        }
        new Thread(new DownLoadThread(threadId, startPos, endPos, PATH))
            .start();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  //       
  static class DownLoadThread implements Runnable {
    private int threadId;
    private int startPos;
    private int endPos;
    private String path;
    public DownLoadThread(int threadId, int startPos, int endPos,
        String path) {
      super();
      this.threadId = threadId;
      this.startPos = startPos;
      this.endPos = endPos;
      this.path = path;
    }
    public void run() {
      try {
        URL url = new URL(path);
        String[] str = PATH.split("/");
        String fileName = str[5];
        HttpURLConnection conn = (HttpURLConnection) url
            .openConnection();
        //   URL     (    API)
        conn.setRequestMethod("GET");
        //   500      
        conn.setReadTimeout(5000);
        File file = new File(threadId + ".txt");
        if (file.exists() && file.length() > 0) {
          BufferedReader br = new BufferedReader(
              new InputStreamReader(new FileInputStream(file)));
          String saveStartPos = br.readLine();
          if (saveStartPos != null && saveStartPos.length() > 0) {
            startPos = Integer.parseInt(saveStartPos);
          }
        }
        //          ,      (     ),   416
        conn.setRequestProperty("Range", "bytes=" + startPos + "-"
            + endPos);
        RandomAccessFile raf = new RandomAccessFile(fileName, "rwd");//              
        raf.seek(startPos);//          
        System.out.println("  " + threadId + ":" + startPos + "~~"
            + endPos);
        InputStream is = conn.getInputStream();
        byte[] b = new byte[1024 * 1024 * 10];
        int len = -1;
        int newPos = startPos;
        while ((len = is.read(b)) != -1) {
          RandomAccessFile rr = new RandomAccessFile(file, "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 (Exception e) {
        e.printStackTrace();
      }
    }
  }
}

주의사항:
(1)각 스 레 드 다운로드 의 시작 과 끝 위 치 를 계산 하 는 방법 을 이해 합 니 다(마지막 스 레 드 는 포함 되 지 않 습 니 다.0 부터)
시작 위치=(스 레 드 수-1)*스 레 드 마다 다운로드 할 파일 길이(크기)
끝 위치=(스 레 드 수*스 레 드 마다 다운로드 한 파일 크기)-1
(2)마지막 스 레 드 에 분 배 된 다운로드 시작 위 치 는 이전 스 레 드 의 끝 위치 이 고 끝 위 치 는 파일 길이 입 니 다.
그래서 마지막 스 레 드 에서 다운로드 한 파일 의 길 이 는 이전 스 레 드 와 같 지 않 습 니 다.
(3)이번 프 리 젠 테 이 션 다운로드 경 로 는 기본적으로 자바 프로젝트 가 있 는 디 렉 터 리 이 며,디 렉 터 리 에 다운로드 파일 과 같은 이름 의 파일 을 포함 할 수 없습니다.그렇지 않 으 면 프로그램 이 416 네트워크 요청 오 류 를 보고 합 니 다.
(4)개인 적 으로 실현 할 때 저 지 른 오류 conn.setRequestProperty("Range","by tes="+startPos+"-"+endPos);따옴표 에 빈 칸 과 다른 문자 가 있어 서 는 안 된다 는 것 을 주의해 야 합 니 다.저 는 따옴표 안에 빈 칸 이 하나 더 있 지만 잘못된 포 지 셔 닝 은 input Stream 오류 입 니 다.잘못 찾 은 것 은 매우 고 통 스 럽 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기