이 기사에서는 멀티 스레드 Java 다운로드에 대해 설명합니다. 다음과 같이 참조에 대해 공유하십시오.
멀티 스레드 파일을 사용하여 파일을 다운로드하면 파일 다운로드가 더 빨리 완료 될 수 있습니다. 다중 스레드 파일이 빠른 이유는 많은 서버 리소스를 차지하기 때문입니다. 예를 들어 : 서버가 동시에 최대 100 명의 사용자에게 서비스를 제공하고 서버의 한 스레드가 한 사용자에 해당한다고 가정합니다. 100 개의 스레드는 컴퓨터에서 동시에 실행되지 않지만 CPU에 의해 차례로 실행됩니다. Application A가 99 개의 스레드를 사용하여 파일을 다운로드하는 경우 99 명의 사용자의 리소스를 차지하는 것과 같습니다. 1 초 이내에 CPU에 의해 할당 된 평균 실행 시간이 10ms라고 가정합니다. 응용 프로그램 A는 서버에서 1 초 안에 990ms 실행 시간을 얻는 반면, 다른 응용 프로그램에는 1 초 만에 10ms 실행 시간 만 있습니다. 수도꼭지와 마찬가지로 초당의 물 출력이 동일 할 때 10 밀리 초보다 990 밀리 초의 물이 확실히 더 많습니다.
멀티 스레드 다운로드의 구현 프로세스 :
1. 먼저 다운로드 된 파일의 길이를 가져온 다음 로컬 파일의 길이를 설정하십시오.
httpurlconnection.getContentLength (); randomAccessFile 파일 = new randomAccessFile ( "youdao.exe", "rw"); file.setlength (filesize); // 로컬 파일의 길이를 설정합니다.
2. 파일 길이와 스레드 수에 따라 각 스레드의 데이터 길이와 다운로드 위치를 계산하십시오. 예를 들어, 파일의 길이는 6m이고 스레드 수는 3이며, 각 스레드에서 다운로드 한 데이터 길이는 2m이며 각 스레드가 다운로드를 시작하는 위치는 아래 그림에 표시됩니다.
3. HTTP의 범위 헤더 필드를 사용하여 다음과 같이 각 스레드가 다운로드 시작 위치를 지정하십시오. 파일의 2m 위치에서 파일 다운로드를 지정하십시오. 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다. httpurlConnection.setRequestProperty ( "범위", "바이트 = 2097152-");
4. 파일을 저장하고 randomAccessFile 클래스를 사용하여 각 스레드가 로컬 파일에서 데이터를 작성하기 시작하는 위치를 지정하십시오.
RandomAccessFile ThreadFile = 새로운 RandomAccessFile ( "<span style ="font-family : arial, helvetica, sans-serif; "> youdao.exe </span <span style ="font-family : arial, helvetica, sans-serif; ">", "rw"); 파일의 위치
다음은 특정 구현 클래스입니다.
구현 클래스를 작성하기 전에 서버에서 다운로드하고 배포 할 파일을 먼저 배치해야합니다.
디렉토리 D : /tomcat/apache-tomcat-7.0.37/webapps/doudou에 여기에 넣고 d : /tomcat/apache-tomcat-7.0.37/bin에서 startup.bat을 시작합니다.
1. DownloadTest.java
패키지 www.csdn.net.down; import java.io.file; import java.io.fileInputStream; import java.io.fileoutputStream; import java.io.ioexception; import java.io.inputStream; import java.io.randomaccessfile; import java.net.httpponnection; java.net.malformedurlexception; import java.net.url; public class downloadloadtest {public file file; 공개 무작위 AccessFile AccessFile; // 스레드 수 공개 static int residnnum = 3; // 각 스레드는 int blocksize를 다운로드 할 책임이 있습니다. // 액세스 경로 생성 public String path = "http : // localhost : 8080/doudou/youdao.exe"; public static int strandCount; // 수량 public void testdown () {try {// 생성 URL 객체 URL URL = new URL (Path); // httpurlConnection 개체 생성 httpurlConnection httpurlConnection = (httpurlConnection) url .openConnection (); // 요청을 보내는 방법을 설정 httpurlConnection.setRequestMethod ( "get"); // 요청 시간 초과 여부를 설정 httpurlConnection.setConnectTimeout (5000); // HTTPURLCONNECTION 설정 .SetRequestProperty ( "사용자 에이전트", "Mozilla/5.0 (호환 가능; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // 응답이 성공했는지 여부 (httpurlConnection.getResponseCode () == 200) {// 파일 크기를 가져옵니다 int size = httpurlConnection.getContentLength (); System.out.println ( "파일 크기" + 크기); // 파일 생성 파일 = 새 파일 ( "youdao.exe"); AccessFile = New RandomAccessFile (파일, "rwd"); // 파일 크기를 설정 accessFile.setLength (size); // 각 스레드의 크기를 다운로드하여 blocksize = size / strooknum; // (int i = 1; i <= threadNum; i ++) {// 1 2 3 // 각 스레드의 시작 위치를 계산하기 위해이 파일을 작동시키기 위해 세 개의 스레드를 엽니 다. // 종료 위치 int endize = (i) * blocksize; // 스레드가 마지막 스레드 인 경우 (i == ThreadNum) {// 파일 크기가 계산 된 엔드 위치보다 큰지 (size> endize) {// 끝 위치는 파일 크기가 endsize = size; }} // 각 스레드에 대해 무작위 읽기를 만듭니다 randomArdAcCessFile ThreadAccessFile = new RandomAccessFile (파일, "rwd"); 새 스레드 (new downloadthread (i, threadaccessfile, startize, endize, path)). start (); }}} catch (marformedurlexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } catch (ioexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); }} public static void main (String [] args) {downloadTest downloadTest = new DownloadTest (); // 다운로드 방법 다운로드 테스트를 호출합니다 .TestDown (); }} class downloadloadThe Read는 실행 가능 {// 다운로드 파일의 캡슐화 public RandomAccessFile AccessFile; // 각 스레드는 ac 공개 int는 종료됩니다. // 파일의 경로 경로 다운로드 공개 문자열 경로; 공개 int 스레드; // 스레드 공개 다운로드를 식별합니다. this.accessfile = accessfile; this.startsize = startsize; this.endsize = endize; this.path = 경로; } @override public void run () {// 실행 메소드 실행 방법 try {// 파일 작성 threadfile = new File (ThreadId + ".txt"); if (readfile.exists ()) {// 파일의 내용을 읽습니다. // 파일의 입력 스트림 객체 생성 파일 파일을 작성하십시오. // 바이트 클래스를 사용하여 바이트 데이터를 읽습니다 [] = streamTools.istodata (fis); // 문자열로 변환 stridelen = 새 문자열 (data); if ((threadlen! = null) && (! "". equals (threadlen))) {statestize = integer.valueof (threadlen); // 416bug if (stightize> endsize) {statgetize = endize -1; }}} // URL 개체 생성 URL URL = 새 URL (PATH); // httpurlConnection 개체 생성 httpurlConnection httpurlConnection = (httpurlConnection) url .openConnection (); // 요청 헤더 설정 httpurlConnection.setRequestMethod ( "get"); // 요청 시간 초과 여부를 설정 httpurlConnection.setConnectTimeout (5000); // HTTPURLCONNECTION 설정 .SetRequestProperty ( "사용자 에이전트", "Mozilla/5.0 (호환 가능; MSIE 10.0; Windows NT 6.2; Trident/6.0)"); // 키 설정 httpurlConnection.setRequestProperty ( "Range", "bytes =" + stightize + "-" + endize); // 현재 스레드 System.out.println ( "현재 스레드" + ThreadId + "출력 시작 위치 :" + STARTINE + "다운로드 종료 위치 :" + ENDSIZE); // 성공적인 응답 // 무작위 읽기 시작 위치를 설정합니다. accessfile.seek (stightize); // 해당 스트림 객체를 가져옵니다. inputStream은 = httpurlConnection.getInputStream (); // 출력 스트림 객체 생성 바이트 버퍼 [] = 새로운 바이트 [1024]; int len = 0; int ThreadTotal = 0; // 각 스레드가 다운로드 된 후 레코드 저장/ while ((len = is.read (buffer))! = -1) {accessfile.write (buffer, 0, len); ThreadTotal += len; // 쓰기 길이를 녹음 // xml 파일 // 파일 파일의 길이를 파일 파일을 통해 다운로드하는 길이를 녹음합니다. foS = new FileOutputStream (ThreadFile); fos.write ((threadTotal + "") .getBytes ()); fos.flush (); fos.close (); } accessFile.close (); is.close (); System.out.println (ThreadId + "스레드 실행이 완료되었습니다"); // 스레드 작동 동기화 (downloadTest.Class) {downloadloadTest.threadCount ++; if (downloadTest.threadCount> = downloadLoadTest.threadnum) {for (int i = 1; i <= downloadTest.threadnum; i ++) {file file = 새 파일 (i+". txt"); if (file.exists ()) {file.delete (); }}}}} catch (marformedurlexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } catch (ioexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); }}}2. StreamTools.java 스트리밍 도구의 캡슐화
패키지 www.csdn.net.down; import java.io.bytearrayoutputstream; import java.io.ioexception; import java.io.inputStream; public stintodata [] istodata (inputStream is) ioexception {// bytearRayoutStream (bytearRayoutStream); // 데이터를 읽기위한 버퍼 영역 바이트 버퍼 [] = 새로운 바이트 [1024]; // 길이 레코드를 읽습니다 int len = 0; // 루프 reading while ((len = is.read (buffer))! = -1) {bops.write (buffer, 0, len); } // 읽기 내용을 바이트 배열 바이트 데이터로 변환 [] = bops.tobytearray (); bops.flush (); bops.close (); is.close (); 반환 데이터; }}이 기사가 모든 사람의 Java 프로그래밍에 도움이되기를 바랍니다.