斷點續傳的原理
其實斷點續傳的原理很簡單
打個比方
假設服務器域名為
GET /down
Accept: image/gif
excel
Accept
Accept
User
Connection: Keep
服務器收到請求後
Content
Accept
Date=Mon
ETag=W/
Content
Server=Microsoft
Last
所謂斷點續傳
下面是用自己編的一個
GET /down
User
RANGE: bytes=
Accept: text/html
仔細看一下就會發現多了一行 RANGE: bytes=
這一行的意思就是告訴服務器 down
服務器收到這個請求以後
Content
Content
Date=Mon
ETag=W/
Content
Server=Microsoft
Last
和前面服務器返回的信息比較一下
Content
返回的代碼也改為
知道了以上原理
Java 實現斷點續傳的關鍵幾點
(
當然用最原始的 Socket 是肯定能完成的
URL url = new URL(
HttpURLConnection httpConnection = (HttpURLConnection)url
// 設置 User
(
// 設置斷點續傳的開始位置
(
// 獲得輸入流
InputStream input = ();
從輸入流中取出的字節流就是 down
保存文件采用的方法
我采用的是 IO 包中的 RandAccessFile 類
操作相當簡單
RandomAccess oSavedFile = new RandomAccessFile(
long nPos =
// 定位文件指針到 nPos 位置
oSavedFile
byte[] b = new byte[
int nRead;
// 從輸入流中讀入字節流
while((nRead=input
{
oSavedFile
}
怎麼樣
斷點續傳內核的實現
主要用了
SiteFileFetch
FileSplitterFetch
FileAccess
SiteInfoBean
Utility
TestMethod
下面是源程序
/*
/*
* SiteFileFetch
*/
package NetFox;
import java
import
public class SiteFileFetch extends Thread {
SiteInfoBean siteInfoBean = null; // 文件信息 Bean
long[] nStartPos; // 開始位置
long[] nEndPos; // 結束位置
FileSplitterFetch[] fileSplitterFetch; // 子線程對象
long nFileLength; // 文件長度
boolean bFirst = true; // 是否第一次取文件
boolean bStop = false; // 停止標志
File tmpFile; // 文件下載的臨時信息
DataOutputStream output; // 輸出到文件的輸出流
public SiteFileFetch(SiteInfoBean bean) throws IOException
{
siteInfoBean = bean;
//tmpFile = File
tmpFile = new File(bean
if(tmpFile
{
bFirst = false;
read_nPos();
}
else
{
nStartPos = new long[bean
nEndPos = new long[bean
}
}
public void run()
{
// 獲得文件長度
// 分割文件
// 實例 FileSplitterFetch
// 啟動 FileSplitterFetch 線程
// 等待子線程返回
try{
if(bFirst)
{
nFileLength = getFileSize();
if(nFileLength ==
{
System
}
else if(nFileLength ==
{
System
}
else
{
for(int i=
{
nStartPos[i] = (long)(i*(nFileLength/nStartPos
}
for(int i=
{
nEndPos[i] = nStartPos[i+
}
nEndPos[nEndPos
}
}
// 啟動子線程
fileSplitterFetch = new FileSplitterFetch[nStartPos
for(int i=
{
fileSplitterFetch[i] = new FileSplitterFetch(siteInfoBean
siteInfoBean
nStartPos[i]
Utility
+ nEndPos[i]);
fileSplitterFetch[i]
}
// fileSplitterFetch[nPos
siteInfoBean
+ siteInfoBean
// Utility
nEndPos =
// fileSplitterFetch[nPos
// 等待子線程結束
//int count =
// 是否結束 while 循環
boolean breakWhile = false;
while(!bStop)
{
write_nPos();
Utility
breakWhile = true;
for(int i=
{
if(!fileSplitterFetch[i]
{
breakWhile = false;
break;
}
}
if(breakWhile)
break;
//count++;
//if(count>
// siteStop();
}
System
}
catch(Exception e){e
}
// 獲得文件長度
public long getFileSize()
{
int nFileLength =
try{
URL url = new URL(siteInfoBean
HttpURLConnection httpConnection = (HttpURLConnection)url
(
int responseCode=();
if(responseCode>=
{
processErrorCode(responseCode);
return
}
String sHeader;
for(int i=
{
//DataInputStream in = new DataInputStream( ());
//Utility
sHeader=(i);
if(sHeader!=null)
{
if(sHeader
{
nFileLength = Integer
break;
}
}
else
break;
}
}
catch(IOException e){e
catch(Exception e){e
Utility
return nFileLength;
}
// 保存下載信息(文件指針位置)
private void write_nPos()
{
try{
output = new DataOutputStream(new FileOutputStream(tmpFile));
output
for(int i=
{
// output
output
output
}
output
}
catch(IOException e){e
catch(Exception e){e
}
// 讀取保存的下載信息(文件指針位置)
private void read_nPos()
{
try{
DataInputStream input = new DataInputStream(new FileInputStream(tmpFile));
int nCount = input
nStartPos = new long[nCount];
nEndPos = new long[nCount];
for(int i=
{
nStartPos[i] = input
nEndPos[i] = input
}
input
}
catch(IOException e){e
catch(Exception e){e
}
private void processErrorCode(int nErrorCode)
{
System
}
// 停止文件下載
public void siteStop()
{
bStop = true;
for(int i=
fileSplitterFetch[i]
}
}
/*
**FileSplitterFetch
*/
package NetFox;
import java
import
public class FileSplitterFetch extends Thread {
String sURL; //File URL
long nStartPos; //File Snippet Start Position
long nEndPos; //File Snippet End Position
int nThreadID; //Thread
boolean bDownOver = false; //Downing is over
boolean bStop = false; //Stop identical
FileAccessI fileAccessI = null; //File Access interface
public FileSplitterFetch(String sURL
throws IOException
{
this
this
this
nThreadID = id;
fileAccessI = new FileAccessI(sName
}
public void run()
{
while(nStartPos < nEndPos && !bStop)
{
try{
URL url = new URL(sURL);
HttpURLConnection httpConnection = (HttpURLConnection)url
(
String sProperty =
(
Utility
InputStream input = ();
//logResponseHead(httpConnection);
byte[] b = new byte[
int nRead;
while((nRead=input
&& !bStop)
{
nStartPos += fileAccessI
//if(nThreadID ==
// Utility
}
Utility
bDownOver = true;
//nPos = fileAccessI
}
catch(Exception e){e
}
}
// 打印回應的頭信息
public void logResponseHead(HttpURLConnection con)
{
for(int i=
{
String header=con
if(header!=null)
//responseHeaders
Utility
else
break;
}
}
public void splitterStop()
{
bStop = true;
}
}
/*
**FileAccess
*/
package NetFox;
import java
public class FileAccessI implements Serializable{
RandomAccessFile oSavedFile;
long nPos;
public FileAccessI() throws IOException
{
this(
}
public FileAccessI(String sName
{
oSavedFile = new RandomAccessFile(sName
this
oSavedFile
}
public synchronized int write(byte[] b
{
int n =
try{
oSavedFile
n = nLen;
}
catch(IOException e)
{
e
}
return n;
}
}
/*
**SiteInfoBean
*/
package NetFox;
public class SiteInfoBean {
private String sSiteURL; //Site
private String sFilePath; //Saved File
private String sFileName; //Saved File
private int nSplitter; //Count of Splited Downloading File
public SiteInfoBean()
{
//default value of nSplitter is
this(
}
public SiteInfoBean(String sURL
{
sSiteURL= sURL;
sFilePath = sPath;
sFileName = sName;
this
}
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;
}
public void setNSplitter(int nCount)
{
nSplitter = nCount;
}
}
/*
**Utility
*/
package NetFox;
public class Utility {
public Utility()
{
}
public static void sleep(int nSecond)
{
try{
Thread
}
catch(Exception e)
{
e
}
}
public static void log(String sMsg)
{
System
}
public static void log(int sMsg)
{
System
}
}
/*
**TestMethod
*/
package NetFox;
public class TestMethod {
public TestMethod()
{ ///xx/weblogic
try{
SiteInfoBean bean = new SiteInfoBean(
//SiteInfoBean bean = new SiteInfoBean(
SiteFileFetch fileFetch = new SiteFileFetch(bean);
fileFetch
}
catch(Exception e){e
}
public static void main(String[] args)
{
new TestMethod();
}
}
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26131.html