This article is about the continuation of the Android breakpoint content, in the form of a detailed description of the case.
first, the principle of the continuation of the breakpoint
In fact, the principle of the continuation of the breakpoint is very simple, is the HTTP request and the general download is different.
For example, when a browser requests a text on the server, the request is made as follows:
Suppose the server domain name is www.jizhuomi.com/android and the file name is Down.zip.
Get/down.zip http/1.1
Accept:image/gif, Image/x-xbitmap, Image/jpeg, Image/pjpeg, application/vnd.ms-
Excel, Application/msword, Application/vnd.ms-powerpoint, */*
Accept-language:zh-cn
Accept-encoding:gzip, deflate
user-agent:mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Connection:keep-alive
After the server receives the request, it looks for the requested file, extracts the file's information, and returns it to the browser, returning the following information:
200
content-length=106786028
Accept-ranges=bytes
Date=mon, Apr 2001 12:56:11 GMT
etag=w/"02ca57e173c11:95b"
Content-type=application/octet-stream
server=microsoft-iis/5.0
Last-modified=mon, Apr 2001 12:56:11 GMT
The so-called breakpoint continuation, that is, from the file has been downloaded from the place to continue to download. So when the client browser passes to the Web server, add a message-where to start.
The following is a "browser" of your own to pass the request information to the Web server, which requires starting from 2000070 bytes.
Get/down.zip http/1.0
User-agent:netfox
range:bytes=2000070-
Accept:text/html, Image/gif, Image/jpeg, *; Q=.2, */*; q=.2
Take a closer look and you'll find one more line range:bytes=2000070-
This line is meant to tell the server that the file is down.zip from 2000070 bytes and that the preceding byte is not to be transmitted.
After the server receives this request, the information returned is as follows:
206
content-length=106786028
Content-range=bytes 2000070-106786027/106786028
Date=mon, Apr 2001 12:55:20 GMT
etag=w/"02ca57e173c11:95b"
Content-type=application/octet-stream
server=microsoft-iis/5.0
Last-modified=mon, Apr 2001 12:55:20 GMT
Compared to the information returned by the previous server, you will see an added line:
Content-range=bytes 2000070-106786027/106786028
The returned code is also changed to 206, and is no longer 200.
Knowing the above principles, you can proceed to the programming of the continuation of the breakpoint.
Two, the key points that the Java realizes the breakpoint to continue to transmit
What method is used to implement submitting range:bytes=2000070-?
Of course, with the most original socket is certainly able to complete, but it is too much trouble, in fact, Java NET package provides this functionality. The code is as follows:
Java code
URL url = new URL ("Http://www.jizhuomi.com/android/down.zip");
HttpURLConnection httpconnection = (httpurlconnection) url.openconnection ();
Set User-agent httpconnection.setrequestproperty ("User-agent", "Netfox");
Set the start position of the breakpoint Httpconnection.setrequestproperty ("range", "bytes=2000070");
Get input stream InputStream input = Httpconnection.getinputstream ();
The byte stream that is fetched from the input stream is the byte stream that the Down.zip file starts with 2000070.
You see, in fact, the continuation of the breakpoint in Java to achieve a very simple bar.
The next thing to do is how to save the obtained stream into the file.
The method used to save the file: I am using the Randaccessfile class in the IO package.
The operation is fairly simple, assuming the file is saved from 2000070, the code is as follows: Java code randomaccess osavedfile = new Randomaccessfile ("Down.zip", "RW");
Long NPOs = 2000070;
Locate the file pointer to the NPOs position Osavedfile.seek (NPOs);
Byte[] B = new byte[1024];
int nread;
Reads a byte stream from the input stream and writes to the file while ((Nread=input.read (b,0,1024) > 0) {osavedfile.write (b,0,nread);
How is it, it's easy. The next thing to do is to integrate into a complete program.
Including a series of line program control system and so on.
Third, the implementation of the breakpoint extension kernel is mainly used in 6 classes, including a test class.
Sitefilefetch.java is responsible for crawling the entire file, controlling internal threads (Filesplitterfetch classes). FilEsplitterfetch.java is responsible for the capture of some files.
Fileaccess.java is responsible for the storage of files.
Siteinfobean.java information about the files you want to crawl, such as the directory where the file is saved, the name, the URL of the crawl file, and so on.
Utility.java Tool class, put some simple methods.
Testmethod.java Test class.
Four, the source code below is the original program: Java code/* **sitefilefetch.java * * Package netfox;
Import java.io.*;
Import java.net.*;
public class Sitefilefetch extends thread {Siteinfobean Siteinfobean = null;//file Information bean long[] nstartpos;//Start position Long[] Nendpos; End position filesplitterfetch[] Filesplitterfetch; Child thread object long nfilelength; File Length Boolean bfirst = true; Whether to fetch the file for the first time Boolean bstop = false; Stop flag file tmpfile; The temporary information of the file download DataOutputStream output;
Output to file output stream public Sitefilefetch (Siteinfobean Bean) throws IOException {Siteinfobean = bean;
Tmpfile = File.createtempfile ("Zhong", "1111", New file (Bean.getsfilepath ());
tmpfile = new File (Bean.getsfilepath () +file.separator + bean.getsfilename () + ". Info");
if (tmpfile.exists ()) {bfirst = false;
Read_npos (); } else {Nstartpos = New Long[bean.getnsplitter ()];
Nendpos = new Long[bean.getnsplitter ()];
} public void Run () {//Get file length//split file//instance Filesplitterfetch//Start Filesplitterfetch thread/wait child thread to return try{
if (bfirst) {nfilelength = GetFileSize ();
if (nfilelength = = 1) {system.err.println ("file length is not known!");
else if (nfilelength = = 2) {system.err.println ("file is not access!");
else {for (int i=0;i<nstartpos.length;i++) {Nstartpos = (long) (i* (nfilelength/nstartpos.length));
for (int i=0;i<nendpos.length-1;i++) {nendpos = nstartpos[i+1];
} nendpos[nendpos.length-1] = Nfilelength;
}//Start child thread Filesplitterfetch = new Filesplitterfetch[nstartpos.length]; for (int i=0;i<nstartpos.length;i++) {filesplitterfetch = new Filesplitterfetch (Siteinfobean.getssiteurl (), Sitei
Nfobean.getsfilepath () + File.separator + siteinfobean.getsfilename (), nstartpos,nendpos,i); Utility.log ("thread" + i + ", Nstartpos =" + NSTartpos + ", Nendpos =" + Nendpos);
Filesplitterfetch.start (); }//Filesplitterfetch[npos.length-1] = new Filesplitterfetch (Siteinfobean.getssiteurl (), Siteinfobean.getsfilepath (
) + File.separator + siteinfobean.getsfilename (), npos[npos.length-1],nfilelength,npos.length-1);
Utility.log ("Thread" + (npos.length-1) + ", Nstartpos =" + npos[npos.length-1] + ", Nendpos =" + nfilelength);
Filesplitterfetch[npos.length-1].start ();
Wait child thread End//int count = 0;
Whether to end While loop Boolean breakwhile = false;
while (!bstop) {write_npos ();
Utility.sleep (500);
Breakwhile = true;
for (int i=0;i<nstartpos.length;i++) {if (!filesplitterfetch.bdownover) {breakwhile = false;
Break
} if (breakwhile) break;
count++;
if (count>4)//Sitestop (); System.err.println ("File download end!")
");
catch (Exception e) {E.printstacktrace ();}
//Get file length public long getfilesize () {int nfilelength =-1; try{URL url =New URL (Siteinfobean.getssiteurl ());
HttpURLConnection httpconnection = (httpurlconnection) url.openconnection ();
Httpconnection.setrequestproperty ("User-agent", "Netfox");
int Responsecode=httpconnection.getresponsecode ();
if (responsecode>=400) {processerrorcode (responsecode); Return-2;
-2 represent access is error} string Sheader; for (int i=1;;;
i++) {//datainputstream in = new DataInputStream (Httpconnection.getinputstream ());
Utility.log (In.readline ());
Sheader=httpconnection.getheaderfieldkey (i); if (sheader!=null) {if (Sheader.equals ("Content-length")) {nfilelength = Integer.parseint (httpconnection.getheader
Field (Sheader));
Break
} else break;
The catch (IOException e) {e.printstacktrace ()}
catch (Exception e) {E.printstacktrace ();}
Utility.log (nfilelength);
return nfilelength; //Save Download information (file pointer location) private void Write_npos () {try{output = new DataOutputStream (New FileOutputStream (Tmpfile));
Output.writeint (nstartpos.length);
for (int i=0;i<nstartpos.length;i++) {//Output.writelong (NPOs);
Output.writelong (Filesplitterfetch.nstartpos);
Output.writelong (Filesplitterfetch.nendpos);
} output.close ();
catch (IOException e) {e.printstacktrace ();}
catch (Exception e) {E.printstacktrace ();} //Read saved download information (file pointer location) private void Read_npos () {try{DataInputStream input = new DataInputStream (New FILEINP
Utstream (tmpfile));
int ncount = Input.readint ();
Nstartpos = new Long[ncount];
Nendpos = new Long[ncount];
for (int i=0;i<nstartpos.length;i++) {nstartpos = Input.readlong ();
Nendpos = Input.readlong ();
} input.close ();
catch (IOException e) {e.printstacktrace ();}
catch (Exception e) {E.printstacktrace ();}
} private void Processerrorcode (int nerrorcode) {system.err.println ("error code:" + Nerrorcode);
//stop file download public void Sitestop () {bstop = true; for (int i=0;i<nstartpos.length;i++) Filesplitterfetch.splitterstop ();
}/* **filesplitterfetch.java * * Package netfox;
Import java.io.*;
Import java.net.*; public class Filesplitterfetch extends thread {string surl;//file url long nstartpos;//file snippet Start Positi on long Nendpos; File snippet end position int nthreadid; Threads ID Boolean bdownover = false; Downing is over Boolean bstop = false; Stop identical Fileaccessi Fileaccessi = null; File access Interface public Filesplitterfetch (string surl,string sname,long nstart,long nend,int id) throws Ioexce
ption {this.surl = sURL;
This.nstartpos = Nstart;
This.nendpos = Nend;
Nthreadid = ID;
Fileaccessi = new Fileaccessi (Sname,nstartpos);
public void Run () {while (Nstartpos < Nendpos &&!bstop) {try{url url = new URL (surl);
HttpURLConnection httpconnection = (httpurlconnection) url.openconnection (); Httpconnection.setrequestproperty ("User-agent", "Netfox");
String sproperty = "bytes=" +nstartpos+ "-";
Httpconnection.setrequestproperty ("range", sproperty);
Utility.log (Sproperty);
InputStream input = Httpconnection.getinputstream ();
Logresponsehead (httpconnection);
Byte[] B = new byte[1024];
int nread; while ((Nread=input.read (b,0,1024)) > 0 && nstartpos < nendpos &&!bstop) {Nstartpos = Fileacce
Ssi.write (B,0,nread);
if (Nthreadid = = 1)//Utility.log ("Nstartpos =" + Nstartpos + ", Nendpos =" + Nendpos);
} utility.log ("thread" + Nthreadid + "is over!");
Bdownover = true;
NPOs = Fileaccessi.write (B,0,nread);
catch (Exception e) {E.printstacktrace ();} }///Print response header information public void Logresponsehead (httpurlconnection con) {for (int i=1;;
i++) {string Header=con.getheaderfieldkey (i);
if (header!=null)//responseheaders.put (Header,httpconnection.getheaderfield (header));
Utility.log (header+ ":" +con.getheaderfield (header));
else break;
}
}public void Splitterstop () {bstop = true;
}/* **fileaccess.java * * Package netfox;
Import java.io.*;
public class Fileaccessi implements serializable{Randomaccessfile Osavedfile;
Long NPOs;
Public Fileaccessi () throws IOException {This ("", 0);
Public Fileaccessi (String Sname,long NPOs) throws IOException {osavedfile = new Randomaccessfile (sname, "RW");
This.npos = NPOs;
Osavedfile.seek (NPOs);
public synchronized int write (byte[] b,int nstart,int nlen) {int n =-1;
try{Osavedfile.write (B,nstart,nlen);
n = nlen;
catch (IOException e) {e.printstacktrace ();
} return N;
}/* **siteinfobean.java * * Package netfox; public class Siteinfobean {private string ssiteurl;//sites URL private string sfilepath;//saved files path pri Vate string sFileName; Saved files name private int nsplitter; Count of splited downloading file public Siteinfobean () {//defAult value of Nsplitter is 5 this ("", "", "", 5);
Public Siteinfobean (String surl,string spath,string sname,int nspiltter) {ssiteurl= surl;
Sfilepath = spath;
sFileName = sname;
This.nsplitter = Nspiltter;
public string Getssiteurl () {return ssiteurl;
public void Setssiteurl (string value) {Ssiteurl = value;
public string Getsfilepath () {return sfilepath;
public void Setsfilepath (string value) {Sfilepath = value;
public string Getsfilename () {return sfilename;
public void Setsfilename (string value) {sfilename = value;
public int Getnsplitter () {return nsplitter;
The public void setnsplitter (int ncount) {nsplitter = ncount;
}/* **utility.java * * Package netfox; Public class Utility {public utility () {} public static void sleep (int nsecond) {try{Thread.Sleep (
Nsecond); catch (Exception e) {e.printstacktrace ();
} public static void log (String smsg) {system.err.println (smsg);
public static void log (int smsg) {system.err.println (smsg);
}/* **testmethod.java * * Package netfox; public class TestMethod {public TestMethod () {///xx/weblogic60b2_win.exe try{Siteinfobean bean = new Siteinf
Obean ("Http://localhost/xx/weblogic60b2_win.exe", "L:\\temp", "Weblogic60b2_win.exe", 5);
Siteinfobean bean = new Siteinfobean ("Http://localhost:8080/down.zip", "L:\\temp", "Weblogic60b2_win.exe", 5);
Sitefilefetch Filefetch = new Sitefilefetch (bean);
Filefetch.start ();
catch (Exception e) {E.printstacktrace ();}
public static void Main (string[] args) {new TestMethod ();
}
}
Above is on the Android breakpoint continued to collate information, follow-up to continue to supplement the relevant information, thank you for your support for this site!