1. package com.test;  
    2.   
    3. import java.io.DataInputStream;  
    4. import java.io.DataOutputStream;  
    5. import java.io.File;  
    6. import java.io.FileInputStream;  
    7. import java.io.FileOutputStream;  
    8. import java.io.IOException;  
    9. import java.io.RandomAccessFile;  
    10. import java.net.HttpURLConnection;  
    11. import java.net.URL;  
    12. /** 
    13.  * 文件断点续传加分段上传线程 
    14.  * @author wzztestin 
    15.  * 
    16.  */  
    17. /** 
    18.  * 文件断点续传加分段上传线程 
    19.  * @author wzztestin 
    20.  * 
    21.  */  
    22. public class DownFileFetch extends Thread {  
    23. null; // 文件信息 Bean  
    24. long[] nStartPos; // 开始位置  
    25. long[] nEndPos; // 结束位置  
    26. // 子线程对象  
    27. long nFileLength; // 文件长度  
    28. boolean bFirst = true; // 是否第一次取文件  
    29. boolean bStop = false; // 停止标志  
    30. // 文件下载的临时信息  
    31. // 输出到文件的输出流  
    32. boolean fileflag; //是本地上传还是远程下载的标志  
    33. //本地文件下载  
    34. int splitter = 0;  
    35.       
    36. /** 
    37.      * 下载上传文件抓取初始化 
    38.      * @param bean 
    39.      * @throws IOException 
    40.      */  
    41. public DownFileFetch(DownFileInfoBean bean) throws IOException {  
    42.         siteInfoBean = bean;  
    43. /** 
    44.          * File.separator windows是\,unix是/ 
    45.          */  
    46. new File(bean.getSFilePath() + File.separator  
    47. ".info");  
    48. if (tmpFile.exists()) {  
    49. false;  
    50. //读取已下载的文件信息  
    51.             read_nPos();  
    52. else {  
    53. new long[bean.getNSplitter()];  
    54. new long[bean.getNSplitter()];  
    55.         }  
    56.         fileflag = bean.getFileflag();  
    57.         downfile = bean.getDownfile();  
    58. this.splitter = bean.getNSplitter();  
    59.     }  
    60.   
    61. public void run() {  
    62. // 获得文件长度  
    63. // 分割文件  
    64. // 实例 FileSplitterFetch  
    65. // 启动 FileSplitterFetch 线程  
    66. // 等待子线程返回  
    67. try {  
    68. if (bFirst) {  
    69.                 nFileLength = getFileSize();  
    70. if (nFileLength == -1) {  
    71. "File Length is not known!");  
    72. else if (nFileLength == -2) {  
    73. "File is not access!");  
    74. else {  
    75. for (int i = 0; i < nStartPos.length; i++) {  
    76. long) (i * (nFileLength / nStartPos.length));  
    77.                     }  
    78. for (int i = 0; i < nEndPos.length - 1; i++) {  
    79. 1];  
    80.                     }  
    81. 1] = nFileLength;  
    82.                 }  
    83.             }  
    84. // 启动子线程  
    85. new DownFileSplitterFetch[nStartPos.length];  
    86. for (int i = 0; i < nStartPos.length; i++) {  
    87. new DownFileSplitterFetch(  
    88.                         siteInfoBean.getSSiteURL(), siteInfoBean.getSFilePath()  
    89. "_"+i,  
    90.                         nStartPos[i], nEndPos[i], i,fileflag,downfile,bFirst);  
    91. "Thread " + i + " , nStartPos = " + nStartPos[i]  
    92. ", nEndPos = " + nEndPos[i]);  
    93.                 fileSplitterFetch[i].start();  
    94.             }  
    95. //下载子线程是否完成标志  
    96. boolean breakWhile = false;  
    97. while (!bStop) {  
    98.                 write_nPos();  
    99. 500);  
    100. true;  
    101. for (int i = 0; i < nStartPos.length; i++) {  
    102. if (!fileSplitterFetch[i].bDownOver) {  
    103. false;  
    104. break;  
    105. else{  
    106.                         write_nPos();  
    107.                     }  
    108.                 }  
    109. if (breakWhile){  
    110. break;  
    111.                 }  
    112.             }  
    113.             hebinfile(siteInfoBean.getSFilePath()+ File.separator + siteInfoBean.getSFileName(),splitter);  
    114. "文件下载结束!");  
    115. catch (Exception e) {  
    116.             e.printStackTrace();  
    117.         }  
    118.     }  
    119.       
    120. /** 
    121.      * 获得文件长度 
    122.      * @return 
    123.      */  
    124. public long getFileSize() {  
    125. int nFileLength = -1;  
    126. if(fileflag){  
    127. try {  
    128. new URL(siteInfoBean.getSSiteURL());  
    129.                 HttpURLConnection httpConnection = (HttpURLConnection) url  
    130.                         .openConnection();  
    131. "User-Agent", "NetFox");  
    132. int responseCode = httpConnection.getResponseCode();  
    133. if (responseCode >= 400) {  
    134.                     processErrorCode(responseCode);  
    135. //represent access is error  
    136. return -2;   
    137.                 }  
    138.                 String sHeader;  
    139. for (int i = 1;; i++) {  
    140.                     sHeader = httpConnection.getHeaderFieldKey(i);  
    141. if (sHeader != null) {  
    142. if (sHeader.equals("Content-Length")) {  
    143.                             nFileLength = Integer.parseInt(httpConnection  
    144.                                     .getHeaderField(sHeader));  
    145. break;  
    146.                         }  
    147. else {  
    148. break;  
    149.                     }  
    150.                 }  
    151. catch (IOException e) {  
    152.                 e.printStackTrace();  
    153. catch (Exception e) {  
    154.                 e.printStackTrace();  
    155.             }  
    156.             DownFileUtility.log(nFileLength);  
    157. else{  
    158. try{  
    159.                 File myflie = downfile;  
    160. int)myflie.length();  
    161. catch(Exception e){  
    162.                 e.printStackTrace();  
    163.             }  
    164.             DownFileUtility.log(nFileLength);  
    165.         }  
    166. return nFileLength;  
    167.     }  
    168.   
    169. /** 
    170.      * 保存下载信息(文件指针位置) 
    171.      */  
    172. private void write_nPos() {  
    173. try {  
    174. new DataOutputStream(new FileOutputStream(tmpFile));  
    175.             output.writeInt(nStartPos.length);  
    176. for (int i = 0; i < nStartPos.length; i++) {  
    177.                 output.writeLong(fileSplitterFetch[i].nStartPos);  
    178.                 output.writeLong(fileSplitterFetch[i].nEndPos);  
    179.             }  
    180.             output.close();  
    181. catch (IOException e) {  
    182.             e.printStackTrace();  
    183. catch (Exception e) {  
    184.             e.printStackTrace();  
    185.         }  
    186.     }  
    187.   
    188. /** 
    189.      * 读取保存的下载信息(文件指针位置) 
    190.      */  
    191. private void read_nPos() {  
    192. try {  
    193. new DataInputStream(new FileInputStream(  
    194.                     tmpFile));  
    195. int nCount = input.readInt();  
    196. new long[nCount];  
    197. new long[nCount];  
    198. for (int i = 0; i < nStartPos.length; i++) {  
    199.                 nStartPos[i] = input.readLong();  
    200.                 nEndPos[i] = input.readLong();  
    201.             }  
    202.             input.close();  
    203. catch (IOException e) {  
    204.             e.printStackTrace();  
    205. catch (Exception e) {  
    206.             e.printStackTrace();  
    207.         }  
    208.     }  
    209.       
    210. /** 
    211.      * 输出错误信息 
    212.      * @param nErrorCode 
    213.      */  
    214. private void processErrorCode(int nErrorCode) {  
    215. "Error Code : " + nErrorCode);  
    216.     }  
    217.   
    218. /** 
    219.      * 停止文件下载 
    220.      */  
    221. public void siteStop() {  
    222. true;  
    223. for (int i = 0; i < nStartPos.length; i++)  
    224.             fileSplitterFetch[i].splitterStop();  
    225.     }  
    226.       
    227. /** 
    228.      * 合并文件 
    229.      * @param sName 
    230.      * @param splitternum 
    231.      */  
    232. private void hebinfile(String sName,int splitternum){  
    233. try{  
    234. new File(sName);  
    235. if(file.exists()){  
    236.                 file.delete();  
    237.             }  
    238. new RandomAccessFile(sName,"rw");  
    239. for(int i = 0;i<splitternum;i++){  
    240. try {  
    241. new RandomAccessFile (new File(sName+"_"+i),"r");  
    242. byte[] b = new byte[1024];  
    243. int nRead;  
    244. while ((nRead = input.read(b, 0, 1024)) > 0) {  
    245. 0, nRead);  
    246.                     }  
    247.                     input.close();  
    248. catch (Exception e) {  
    249.                     e.printStackTrace();  
    250.                 }  
    251.             }  
    252. "file size is "+saveinput.length());  
    253. catch(Exception e){  
    254.             e.printStackTrace();  
    255.         }  
    256.     }  
    257.       
    258. /** 
    259.      * 写文件 
    260.      * @param b 
    261.      * @param nStart 
    262.      * @param nLen 
    263.      * @return 
    264.      */  
    265. private int write(RandomAccessFile oSavedFile,byte[] b, int nStart, int nLen) {  
    266. int n = -1;  
    267. try {  
    268.             oSavedFile.seek(oSavedFile.length());  
    269.             oSavedFile.write(b, nStart, nLen);  
    270.             n = nLen;  
    271. catch (IOException e) {  
    272.             e.printStackTrace();  
    273.         }  
    274. return n;  
    275.     }  
    276. }

    Java代码

    1. package com.test;  
    2.   
    3. import java.io.File;  
    4. import java.io.IOException;  
    5. import java.io.InputStream;  
    6. import java.io.RandomAccessFile;  
    7. import java.net.HttpURLConnection;  
    8. import java.net.URL;  
    9. /** 
    10.  * 下载上传子线程 
    11.  * @author wzztestin 
    12.  * 
    13.  */  
    14. public class DownFileSplitterFetch extends Thread {  
    15. // 下载文件的地址  
    16. long nStartPos; // 文件分段的开始位置  
    17. long nEndPos; // 文件分段的结束位置  
    18. int nThreadID; // 线程的 ID  
    19. boolean bDownOver = false; // 是否下载完成  
    20. boolean bStop = false; // 停止下载  
    21. null; // 文件对象  
    22. boolean fileflag; //是URL下载还是本地下载  
    23. null;//本地下载文件  
    24. boolean bFirst = true;  
    25.       
    26. /** 
    27.      * 下载,上传子线程初始化 
    28.      * @param sURL 
    29.      * @param sName 
    30.      * @param nStart 
    31.      * @param nEnd 
    32.      * @param id 
    33.      * @param fileflag 
    34.      * @param downfile 
    35.      * @throws IOException 
    36.      */  
    37. public DownFileSplitterFetch(String sURL, String sName, long nStart, long nEnd,  
    38. int id,boolean fileflag,File downfile,boolean bFirst) throws IOException {  
    39. this.sURL = sURL;  
    40. this.nStartPos = nStart;  
    41. this.nEndPos = nEnd;  
    42.         nThreadID = id;  
    43. new DownFileAccess(sName, nStartPos,bFirst);  
    44. this.fileflag = fileflag;  
    45. this.file = downfile;  
    46. this.bFirst = bFirst;  
    47.     }  
    48.       
    49. /** 
    50.      * 线程执行 
    51.      */  
    52. public void run() {  
    53. if(fileflag){  
    54. this.urldownload();  
    55. else{  
    56. this.filedownload();  
    57.         }  
    58.     }  
    59.   
    60. /** 
    61.      * 打印回应的头信息 
    62.      * @param con 
    63.      */  
    64. public void logResponseHead(HttpURLConnection con) {  
    65. for (int i = 1;; i++) {  
    66.             String header = con.getHeaderFieldKey(i);  
    67. if (header != null){  
    68. " : " + con.getHeaderField(header));  
    69. else{  
    70. break;  
    71.             }  
    72.         }  
    73.     }  
    74.       
    75. /** 
    76.      * 地址下载 
    77.      */  
    78. private void urldownload(){  
    79. "Thread " + nThreadID + " url down filesize is "+(nEndPos-nStartPos));  
    80. "Thread " + nThreadID + " url start >> "+nStartPos +"------end >> "+nEndPos);  
    81. while (nStartPos < nEndPos && !bStop) {  
    82. try {  
    83. new URL(sURL);  
    84.                 HttpURLConnection httpConnection = (HttpURLConnection) url  
    85.                         .openConnection();  
    86. "User-Agent", "NetFox");  
    87. "bytes=" + nStartPos + "-";  
    88. "RANGE", sProperty);  
    89.                 DownFileUtility.log(sProperty);  
    90.                 InputStream input = httpConnection.getInputStream();  
    91. byte[] b = new byte[1024];  
    92. int nRead;  
    93. while ((nRead = input.read(b, 0, 1024)) > 0  
    94.                         && nStartPos < nEndPos && !bStop) {  
    95. if((nStartPos+nRead)>nEndPos)  
    96.                     {  
    97. int)(nEndPos - nStartPos);  
    98.                     }  
    99. 0, nRead);  
    100.                 }  
    101. "Thread " + nThreadID + " nStartPos : "+nStartPos);  
    102.                 fileAccessI.oSavedFile.close();  
    103. "Thread " + nThreadID + " is over!");  
    104.                 input.close();  
    105. true;  
    106. catch (Exception e) {  
    107.                 e.printStackTrace();  
    108.             }  
    109.         }  
    110. if(!bDownOver){  
    111. if(nStartPos >= nEndPos){  
    112. true;  
    113.             }  
    114.         }  
    115.     }  
    116.       
    117. /** 
    118.      * 文件下载 
    119.      */  
    120. private void filedownload(){  
    121. "Thread " + nThreadID + " down filesize is "+(nEndPos-nStartPos));  
    122. "Thread " + nThreadID + " start >> "+nStartPos +"------end >> "+nEndPos);  
    123. while (nStartPos < nEndPos && !bStop) {  
    124. try {  
    125. new RandomAccessFile(file,"r");  
    126.                 input.seek(nStartPos);  
    127. byte[] b = new byte[1024];  
    128. int nRead;  
    129. while ((nRead = input.read(b, 0, 1024)) > 0  
    130.                         && nStartPos < nEndPos && !bStop) {  
    131. if((nStartPos+nRead)>nEndPos)  
    132.                     {  
    133. int)(nEndPos - nStartPos);  
    134.                     }  
    135. 0, nRead);  
    136.                 }  
    137.                 fileAccessI.oSavedFile.close();  
    138. "Thread " + nThreadID + " is over!");  
    139.                 input.close();  
    140. true;  
    141.                 input.close();  
    142. catch (Exception e) {  
    143.                 e.printStackTrace();  
    144.             }  
    145.         }  
    146. if(!bDownOver){  
    147. if(nStartPos >= nEndPos){  
    148. true;  
    149.             }  
    150.         }  
    151. "Thread " + nThreadID + "last start >> "+nStartPos );  
    152.     }  
    153.       
    154. /** 
    155.      * 停止 
    156.      */  
    157. public void splitterStop() {  
    158. true;  
    159.     }  
    160. }

     

    Java代码  

    1. package com.test;  
    2.   
    3. import java.io.*;  
    4.   
    5. /** 
    6.  * 文件对象 
    7.  * @author wzztestin 
    8.  * 
    9.  */  
    10. public class DownFileAccess implements Serializable {  
    11. /** 
    12.      *  
    13.      */  
    14. private static final long serialVersionUID = -2518013155676212866L;  
    15. //写入文件的流  
    16.     RandomAccessFile oSavedFile;  
    17. //开始位置  
    18. long nPos;  
    19. boolean bFirst;  
    20.   
    21. public DownFileAccess() throws IOException {  
    22. this("", 0,true);  
    23.     }  
    24.       
    25. /** 
    26.      * 写入文件初始化 
    27.      * @param sName 
    28.      * @param nPos 
    29.      * @throws IOException 
    30.      */  
    31. public DownFileAccess(String sName, long nPos,boolean bFirst) throws IOException {  
    32. new File(sName);  
    33. new RandomAccessFile(wfile,"rw");  
    34. if(!bFirst){  
    35.             oSavedFile.seek(wfile.length());  
    36.         }  
    37. this.nPos = nPos;  
    38. this.bFirst = bFirst;  
    39.     }  
    40.       
    41. /** 
    42.      * 写文件 
    43.      * @param b 
    44.      * @param nStart 
    45.      * @param nLen 
    46.      * @return 
    47.      */  
    48. public synchronized int write(byte[] b, int nStart, int nLen) {  
    49. int n = -1;  
    50. try {  
    51.             oSavedFile.write(b, nStart, nLen);  
    52.             n = nLen;  
    53. catch (IOException e) {  
    54.             e.printStackTrace();  
    55.         }  
    56. return n;  
    57.     }  
    58. }

     

    Java代码  

    1. package com.test;  
    2.   
    3. import java.io.File;  
    4.   
    5. public class DownFileInfoBean {  
    6. private String sSiteURL; // 文件的下载地址  
    7. private String sFilePath; // 保存文件的路径  
    8. private String sFileName; // 保存文件的名字  
    9. private int nSplitter; // 文件分成几段,默认是5段  
    10. private boolean fileflag; // 如果为FALSE则是本地下载,为TRUE则URL下载  
    11. private File downfile;  
    12.   
    13. public File getDownfile() {  
    14. return downfile;  
    15.     }  
    16.   
    17. public void setDownfile(File downfile) {  
    18. this.downfile = downfile;  
    19.     }  
    20.   
    21. public boolean getFileflag() {  
    22. return fileflag;  
    23.     }  
    24.   
    25. public void setFileflag(boolean fileflag) {  
    26. this.fileflag = fileflag;  
    27.     }  
    28.       
    29. /** 
    30.      * 默认初始化 
    31.      */  
    32. public DownFileInfoBean() {  
    33. // default 5  
    34. this("", "", "", 5,false,null);  
    35.     }  
    36.       
    37. /** 
    38.      * 下载文件信息初始化 
    39.      * @param sURL 下载的链接地址 
    40.      * @param sPath 上传的保存路径 
    41.      * @param sName 上传保存的文件名 
    42.      * @param nSpiltter 文件分段个数 
    43.      * @param fileflag 是本地文件上传下载还是链接上传下载的标志 
    44.      * @param downfile 本地下载文件(FILE) 
    45.      */  
    46. public DownFileInfoBean(String sURL, String sPath, String sName, int nSpiltter,boolean fileflag,File downfile) {  
    47.         sSiteURL = sURL;  
    48.         sFilePath = sPath;  
    49.         sFileName = sName;  
    50. this.nSplitter = nSpiltter;  
    51. this.fileflag = fileflag;  
    52. this.downfile = downfile;  
    53.     }  
    54.   
    55. public String getSSiteURL() {  
    56. return sSiteURL;  
    57.     }  
    58.   
    59. public void setSSiteURL(String value) {  
    60.         sSiteURL = value;  
    61.     }  
    62.   
    63. public String getSFilePath() {  
    64. return sFilePath;  
    65.     }  
    66.   
    67. public void setSFilePath(String value) {  
    68.         sFilePath = value;  
    69.     }  
    70.   
    71. public String getSFileName() {  
    72. return sFileName;  
    73.     }  
    74.   
    75. public void setSFileName(String value) {  
    76.         sFileName = value;  
    77.     }  
    78.   
    79. public int getNSplitter() {  
    80. return nSplitter;  
    81.     }  
    82.   
    83. public void setNSplitter(int nCount) {  
    84.         nSplitter = nCount;  
    85.     }  
    86. }

     

    Java代码  

    1. package com.test;  
    2.   
    3. /** 
    4.  * 简单的工具类 
    5.  * @author wzztestin 
    6.  * 
    7.  */  
    8. public class DownFileUtility {  
    9. public DownFileUtility() {  
    10.     }  
    11.       
    12. /** 
    13.      * 休眠时长 
    14.      * @param nSecond 
    15.      */  
    16. public static void sleep(int nSecond) {  
    17. try {  
    18.             Thread.sleep(nSecond);  
    19. catch (Exception e) {  
    20.             e.printStackTrace();  
    21.         }  
    22.     }  
    23.       
    24. /** 
    25.      * 打印日志信息 
    26.      * @param sMsg 
    27.      */  
    28. public static void log(String sMsg) {  
    29.         System.err.println(sMsg);  
    30.     }  
    31.       
    32. /** 
    33.      * 打印日志信息 
    34.      * @param sMsg 
    35.      */  
    36. public static void log(int sMsg) {  
    37.         System.err.println(sMsg);  
    38.     }  
    39. }

     

    Java代码  

    1. package com.test;  
    2.   
    3. public class TestMethod {  
    4. public TestMethod() {  
    5. try {  
    6. new DownFileInfoBean(  
    7. "http://cdn.market.hiapk.com/data/upload//2012/09_27/17/car.wu.wei.kyo.shandian_174928.apk", "D:\\temp",  
    8. "shandian_174928.apk", 5,true,null);  
    9. /*File file = new File("D:\\dan07.apk"); 
    10.             DownFileInfoBean bean = new DownFileInfoBean(null, "D:\\temp", 
    11.                     "dan07.apk", 3,false,file);*/  
    12. new DownFileFetch(bean);  
    13.             fileFetch.start();  
    14. catch (Exception e) {  
    15.             e.printStackTrace();  
    16.         }  
    17.     }  
    18.   
    19. public static void main(String[] args) {  
    20. new TestMethod();  
    21.     }  
    22. }