A netizen just needs this thing, I put several technologies together. Includes three parts and is implemented one at a time
Multi-threaded file downloads, HTTP protocol
Make this feature an HTTP service that listens on a port for easy use by non-Java systems
Encapsulates this functionality as a Windows service that can be started automatically when the machine starts
We look at the procedure one by one.
One, multithreading download
This mainly uses a range parameter in the HTTP protocol, and he sets the location where you read the data and where it ends. Users who often use flashget should see this often when they view the details of a connection. Like what
range:bytes=100-2000
Represents the start of a 100-byte position, at the end of a 2000-byte position, and 1900 bytes should be read.
The program first gets the length of the file, and then allocates several threads to read each section separately, using the
Randomaccessfile
To read and write at random locations.
The following is the complete download code.
package net.java2000.tools;
import Java.io.BufferedInputStream;
import Java.io.File;
import java.io.IOException;
import Java.io.RandomAccessFile;
import Java.net.URL;
import java.net.URLConnection;
/**
* http multi-threaded download tool.
*
* @author Zhaoqing www.java2000.net
*/
public class Httpdownloader extends Thread {
//page to download
private String page;
//Saved path
private String Savepath;
//Thread Count
private int threadnumber = 2;
//Source Address
private String Referer;
//min. block size. If the file size divided by the number of threads is less than this, the number of threads is reduced.
private int min_block = 10 * 1024;
public static void Main (string[] args) throws Exception {
Httpdownloader d = new Httpdownloader ("Http://www.xxxx.net/xxxx.rar", "D://xxxx.rar", 10);
D.down ();
}
public void Run () {
try {
down ();
} catch (Exception e) {
E.printstacktrace ();
}
}
/**
* Download Operation
*
* @throws Exception
*/
public void Down () throws Exception {
url url = new URL (page); Create URL
urlconnection con = url.openconnection (); Establish a connection
int contentlen = Con.getcontentlength (); Get resource length
if (Contentlen/min_block + 1 < threadnumber) {
threadnumber = contentlen/min_block + 1; Adjust the number of download threads
}
if (Threadnumber > 10) {
threadnumber = 10;
}
int begin = 0;
int step = Contentlen/threadnumber;
int end = 0;
for (int i = 0; i < threadnumber; i++) {
End + = step;
if (end > Contentlen) {
end = Contentlen;
}
New Httpdownloaderthread (this, I, begin, end). Start ();
begin = END;
}
}
public Httpdownloader () {
}
/**
* Download
*
* @param page to be downloaded
* @param savepath saved path
*/
public Httpdownloader (String page, String savepath) {
This (page, Savepath, 10);
}
/**
* Download
*
* @param page to be downloaded
* @param savepath saved path
* @param threadnumber thread Count
*/
public Httpdownloader (String page, string savepath, int threadnumber) {
This (page, page, Savepath, 10);
}
/**
* Download
*
* @param page to be downloaded
* @param savepath saved path
* @param threadnumber thread Count
* @param referer source
*/
public Httpdownloader (String page, String referer, string savepath, int threadnumber) {
this.page = page;
This.savepath = Savepath;
this.threadnumber = threadnumber;
this.referer = Referer;
}
public String GetPage () {
return page;
}
public void Setpage (String page) {
this.page = page;
}
public String Getsavepath () {
return savepath;
}
public void Setsavepath (String savepath) {
This.savepath = Savepath;
}
public int Getthreadnumber () {
return threadnumber;
}
public void Setthreadnumber (int threadnumber) {
this.threadnumber = threadnumber;
}
Public String Getreferer () {
return referer;
}
public void Setreferer (String referer) {
this.referer = Referer;
}
}
/**
* Download Thread
*
* @author Zhaoqing www.java2000.net
*/
class Httpdownloaderthread extends Thread {
Httpdownloader Manager;
int startpos;
int endpos;
int id;
int CurPos;
int buffer_size = 4096;
int readbyte = 0;
Httpdownloaderthread (httpdownloader manager, int id, int startpos, int endpos) {
this.id = ID;
This.manager = Manager;
this.startpos = startpos;
this.endpos = Endpos;
}
public void Run () {
SYSTEM.OUT.PRINTLN ("thread" + ID + "start");
//Create a buff
Bufferedinputstream bis = null;
randomaccessfile fos = null;
//Buffer size
byte[] buf = new Byte[buffer_size];
URLConnection con = null;
try {
File File = new file (Manager.getsavepath ());
//Create Randomaccessfile
fos = new Randomaccessfile (file, rw);
//starting from Startpos
Fos.seek (startpos);
//Create a connection, where a connection is created for each thread
url url = new URL (manager.getpage ());
con = url.openconnection ();
con.setallowuserinteraction (TRUE);
CurPos = startpos;
//sets the scope for obtaining resource data from Startpos to Endpos
con.setrequestproperty ("Range", "bytes=" + startpos + "-" + endpos);
//hotlinking solution
Con.setrequestproperty ("Referer", manager.getreferer () = null? Manager.getpage (): Manager.getreferer ());
con.setrequestproperty ("useragent", "mozilla/4.0" (compatible; MSIE 6.0; Windows NT 5.1) ");
//The following paragraph writes data to a file, CurPos is unknown to the current write, and is judged to be less than Endpos,
//If the Endpos is exceeded, the thread has been executed
bis = new Bufferedinputstream (Con.getinputstream ());
while (CurPos < endpos) {
int len = bis.read (buf, 0, buffer_size);
if (len = = 1) {
break;
}
fos.write (buf, 0, Len);
CurPos = CurPos + len;
if (CurPos > Endpos) {
//Get the number of bytes correctly read
readbyte = len-(curpos-endpos) + 1;
} else {
readbyte = len;
}
}
SYSTEM.OUT.PRINTLN ("thread" + ID + "has been downloaded:" + readbyte);
Bis.close ();
Fos.close ();
} catch (IOException ex) {
Ex.printstacktrace ();
}
}
}