Implementation of Http-based multi-thread download in Java/Android

Source: Internet
Author: User

Reprinted please indicate the source: http://blog.csdn.net/lmj623565791/article/details/26994463

I have a friend who needs a multi-thread example to help implement it. I 'd like to share it with you ~

Let's talk about the principle first. The principle is clear, but it is actually very simple:

A. For a resource on the network, first send a request to return the size of the file to be downloaded from the returned Content-Length, and then create a file based on the file size.

This. fileSize = conn. getContentLength (); // obtain the File size according to the response File dir = new File (dirStr); this. localFile = new File (dir, filename); RandomAccessFile raf = new RandomAccessFile (this. localFile, "rw"); raf. setLength (fileSize); raf. close ();

B. Allocate the downloaded byte interval for each thread based on the number of threads and file size, and then send a request to the server to obtain the file content in the byte interval.

Conn. setRequestProperty ("Range", "bytes =" + startPos + "-" + endPos); // you can specify a Range for retrieving object data.

C. Use the RandomAccessFile seek method to write bytes to a file simultaneously by multiple threads.

raf.seek(startPos);while ((len = is.read(buf)) != -1){raf.write(buf, 0, len);}
After the analysis, the principle is very simple. I encapsulated a class and used the instance of this class for download. required parameters: the URI of the download resource, the local file path, and the number of threads.

Package com. zhy. mutilthread_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; public class MultipartThreadDownloador {/*** address of the resource to be downloaded */private String urlStr;/*** downloaded File */private File localFile; /*** path to the local folder where the file to be downloaded is stored */private String dirStr;/*** file name stored locally */private String filenam E;/*** Number of threads enabled */private int threadCount;/*** File Download size */private long fileSize; public MultipartThreadDownloador (String urlStr, String dirStr, string filename, int threadCount) {this. urlStr = urlStr; this. dirStr = dirStr; this. filename = filename; this. threadCount = threadCount;} public void download () throws IOException {createFileByUrl ();/*** calculate the length of data to be downloaded by each thread */long block = fileSize % threadCount = 0? FileSize/threadCount: fileSize/threadCount + 1; for (int I = 0; I <threadCount; I ++) {long start = I * block; long end = start + block> = fileSize? FileSize: start + block-1; new DownloadThread (new URL (urlStr), localFile, start, end ). start () ;}}/*** obtain the resource Size Based on the Resource URL and create a file locally */public void createFileByUrl () throws IOException {URL url = new URL (urlStr); HttpURLConnection conn = (HttpURLConnection) url. openConnection (); conn. setConnectTimeout (15*1000); conn. setRequestMethod ("GET"); conn. setRequestProperty ("Accept", "image/gif, image/jpeg, image/p Jpeg, image/pjpeg, application/x-shockwave-flash, application/xaml + xml, application/vnd. ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd. ms-excel, application/vnd. ms-powerpoint, application/msword, */* "); conn. setRequestProperty ("Accept-Language", "zh-CN"); conn. setRequestProperty ("Referer", urlStr); conn. setRequestProperty ("Charset", "UTF-8"); conn. setRequestProper Ty ("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0 ;. net clr 1.1.4322 ;. net clr 2.0.50727 ;. net clr 3.0.04506.30 ;. net clr 3.0.20.6.2152 ;. net clr 3.5.30729) "); conn. setRequestProperty ("Connection", "Keep-Alive"); conn. connect (); if (conn. getResponseCode () = 200) {this. fileSize = conn. getContentLength (); // obtain the file size based on the response if (fileSize <= 0) throw new RuntimeException ("the file t Hat you download has a wrong size... "); File dir = new File (dirStr); if (! Dir. exists () dir. mkdirs (); this. localFile = new File (dir, filename); RandomAccessFile raf = new RandomAccessFile (this. localFile, "rw"); raf. setLength (fileSize); raf. close (); System. out. println ("the file size to be downloaded is:" + this. fileSize + ", storage location:" + dirStr + "/" + filename);} else {throw new RuntimeException ("url that you conneted has error... ") ;}} private class DownloadThread extends Thread {/*** download file URI */priva Te URL;/* local path */private File localFile;/* Indicates whether to end */private boolean isFinish; /*** start position */private Long startPos;/*** end position */private Long endPos; public DownloadThread (URL url, File savefile, Long startPos, Long endPos) {this. url = url; this. localFile = savefile; this. startPos = startPos; this. endPos = endPos;} @ Overridepublic void run () {System. out. println (Thread. currentThread (). getName () +" Download... "); try {HttpURLConnection conn = (HttpURLConnection) url. openConnection (); conn. setConnectTimeout (15*1000); conn. setRequestMethod ("GET"); conn. setRequestProperty ("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml + xml, application/vnd. ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd. ms-excel, applicatio N/vnd. ms-powerpoint, application/msword, */* "); conn. setRequestProperty ("Accept-Language", "zh-CN"); conn. setRequestProperty ("Referer", url. toString (); conn. setRequestProperty ("Charset", "UTF-8"); conn. setRequestProperty ("Range", "bytes =" + startPos + "-" + endPos); // you can specify the Range of conn to obtain object data. setRequestProperty ("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0 ;. net clr 1.1.4322 ;. NE T clr 2.0.50727 ;. net clr 3.0.04506.30 ;. net clr 3.0.20.6.2152 ;. net clr 3.5.30729) "); conn. setRequestProperty ("Connection", "Keep-Alive"); conn. connect ();/*** indicates that the server has successfully processed some GET requests */if (conn. getResponseCode () == 206) {InputStream is = conn. getInputStream (); int len = 0; byte [] buf = new byte [1024]; RandomAccessFile raf = new RandomAccessFile (localFile, "rwd"); raf. seek (startPos); while (len = is. read (buf ))! =-1) {raf. write (buf, 0, len);} raf. close (); is. close (); System. out. println (Thread. currentThread (). getName () + "download completed:" + startPos + "--" + endPos); this. isFinish = true;} else {throw new RuntimeException ("url that you conneted has error... ") ;}} catch (IOException e) {e. printStackTrace ();}}}}

The createFileByUrl method is step 1 of the above principles to obtain the file size and create a local file. In the program, I use an internal class DownloadThread to inherit the Thread, which is responsible for downloading. The download () method calculates the byte interval to be downloaded for each thread based on the number of threads and the file size, and then enables the thread to download.

On the server side: I threw a few files to the Tomcat root directory for experiment. The following is the test code:

package com.zhy.mutilthread_download;import java.io.IOException;public class Test{public static void main(String[] args){try{new MultipartThreadDownloador("http://localhost:8080/nexus.zip","f:/backup/nexus", "nexus.zip", 2).download();} catch (IOException e){e.printStackTrace();}}}

Output result:

The size of the file to be downloaded is 31143237, and the storage location is: f:/backup/nexus/nexus.zip Thread-1... start download from Thread-2... start download from Thread-3... start download from Thread-4... thread-4 completed download: 23357430 -- 31143237Thread-2 completed download: 7785810 -- 15571619Thread-1 completed download: 0 -- 7785809Thread-3 completed download: 15571620 -- 23357429

:



OK. The multi-thread download is complete. If the code design is unreasonable and the method is incorrectly used, please leave a message ,,,



Download source code



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.