java源代码详细注释 网络文件下载之分段下载(可扩展 断点续传)
来源:互联网 发布:电子商务美工毕业论文 编辑:程序博客网 时间:2024/06/03 21:37
直接贴出代码
/*********************************************************************** * Module: DownloadConnection.java * Author: Administrator * Purpose: Defines the Class DownloadConnection ***********************************************************************/package com.tiny.httpdemo;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;import lan.Log;/** * 这个下载连接类主要采用的方式是 将文件大小进行分块然后 并且有序下载 * 主要的目的是为了让一次下载的数量不要过于的大 以避免io阻塞 * 若要实现断点续传本程序的改进应该是很方便的 * 记住lastSize 既可以立马进行分解 * @author sada * */public class DownloadConnection {//private static final String mtempurl = "http://219.138.125.22/myweb/mp3/CMP3/JH19.MP3";private static final String mtempurl = "http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%8D%B7%E5%A1%98%E6%9C%88%E8%89%B2.mp3";public static void main(String[] args) {DownloadConnection dConnection = new DownloadConnection(mtempurl, 0);dConnection.download(mtempurl);}/** TAG */private static final String TAG = "Sada.DownloadConnection";/** 用于操作下载暂停,写本地文件时候跳出写循环的标志 */private boolean stop;/** 下载的文件的总长度 */private int totalSize;/** 如果是继续下载,lastSize表示上次已经下载的长度 */private int lastSize;/** 當前下載數據塊已下載數據大小,该变量会在写循环中增加*/private int currSize;/** 当前需要下载的文件大小,用于继续下载时,写循环的结束标志 */private int contentLength;/** 最大塊大小1MB */private static final int MAX_SIZE_ONE_MEGA = 1024 * 1024;private int lastloadsize = 0; //已传的偏移private int currloadsize = 0; //还要传得偏移private int contentlength = 0; //总共要传得大小private int pogresslength = 0; //进度条显示private static byte[] buffer;private int currentPercentage = 0;private RandomAccessFile raf;private File temp;private InputStream is; // 从网络读输入流/*---------------------------------*//** 连接实例 */protected HttpURLConnection conn;/** 连接的完整url */protected String url;/** 响应行的响应码,例如:404, 200, 500, 201等 */protected int responseCode;/** 响应行的响应消息关键字,例如:OK,Created,Unauthorized等 */protected String responseMessage;protected int timeout = -1;/** 文件名*/private String filename = ""; /** 准备请求行 */protected void prepareRequestLine() throws Exception{conn.setRequestMethod("GET");}/** 准备消息头 */protected void prepareHeaders() {int startfilesize = lastloadsize; //当前文件偏移位置int endfilesize = currloadsize - 1; //目的文件偏移位置conn.setAllowUserInteraction(true); // 设置传输位置conn.setRequestProperty("RANGE", "bytes=" + startfilesize + "-" + endfilesize);Log.i(TAG,"(start = " + startfilesize + ")" + " - " + "(end = " + endfilesize + ")");}public void download(String surl){try{int totalsize = 0; //整理后的文件大小URL mUrl = new URL(url);conn = (HttpURLConnection) mUrl.openConnection();// ---------------- 改进totalsize = conn.getContentLength() - this.lastSize;// 本次续下载的大小this.totalSize = conn.getContentLength();pogresslength = this.lastSize; //初始化起始的进度偏移位置 在断点时用到conn.disconnect();Log.e(TAG, "the file size = " + this.totalSize);filename = getFileNameFromUrl(surl);File cache = new File("D:\\TEMP");if(cache != null && !cache.exists()){cache.mkdirs();}temp = new File("D:\\TEMP" + "\\" + filename);raf = new RandomAccessFile(temp, "rw");raf.seek(raf.length());int offset = 0; // 上次下载的位置for(int i = 0 ; i < totalsize / MAX_SIZE_ONE_MEGA ; i++){lastloadsize = offset; //已传偏移currloadsize = lastloadsize + MAX_SIZE_ONE_MEGA; // 将传到的偏移位置contentlength = currloadsize - lastloadsize; // 总共要传的大小Log.v(TAG, "the size long " + contentlength);connect();if(stop){// 暂停下载数据//写数据库 pogresslength已下载长度return;}offset += MAX_SIZE_ONE_MEGA; }if(totalsize % MAX_SIZE_ONE_MEGA > 0){totalsize = totalsize % MAX_SIZE_ONE_MEGA;lastloadsize = offset; //已传偏移currloadsize = lastloadsize + totalsize; //将传到的偏移位置contentlength = currloadsize - lastloadsize; //总共要传得大小Log.v(TAG, "the size long " + contentlength);if(contentlength > 0){ // 当下载最后大小为0时 直接做后面的操作connect();}if(stop){//写数据库 pogresslengthreturn;}}Log.v(TAG, "Download file success!\t\n" + "Size: " + lastloadsize + " bytes.");Log.v(TAG,"lastsize = " + pogresslength);Log.v(TAG,"fileSize = " + this.totalSize);// 更新下载进度到数据库File temp = new File("D:\\TEMP" + "\\" + filename);if(temp != null && temp.exists() && temp.length() != this.totalSize){ // 大小不一致则删除临时文件throw new Exception("The temp file is not completed!");}}catch(Exception e){}finally{if(raf != null){try {raf.close();raf = null;} catch (IOException e) {}}if(conn != null){conn.disconnect();conn = null;}if(is != null){try {is.close();} catch (IOException e) {}is = null;}System.gc();}}public void connect() throws Exception {URL mUrl = new URL(url);conn = (HttpURLConnection) mUrl.openConnection();conn.setDoInput(true);// 2.准备请求行prepareRequestLine();// 3.再准备消息头prepareHeaders();conn.setDoOutput(false);conn.connect();responseCode = conn.getResponseCode();responseMessage = conn.getResponseMessage();Log.d(TAG, "Response:" + responseCode + " " + responseMessage);if(responseCode == 206 && "Partial Content".equals(responseMessage)){contentLength = conn.getContentLength();//Log.d(TAG, "the size long=" + contentLength);is = conn.getInputStream();if(!temp.exists() && pogresslength != 0){// 失败重新开始throw new Exception("The temp file has bean deleted");}currSize = 0;int ch = -1;// 恰好写完while(currSize < contentlength){// 判断是否暂停的标志if(stop){break;}ch = is.read(buffer);if(ch == -1){break;}raf.write(buffer, 0 , ch);currSize += ch;pogresslength = lastloadsize + currSize;if(currSize == contentlength){break;}}//下载进度更新Log.d(TAG, "Download block:\t" + currSize + " bytes. " + contentLength);currSize = 0;is.close();conn.disconnect();conn = null;}else{conn.disconnect();if(conn != null){conn = null;}throw new Exception("Response header is incorrect!Must be: HTTP/1.1 206 Partial Content." + "code = " + responseCode + " message = " + responseMessage);}}/** 暂停下载 */public void pauseDownload() {Log.e(TAG,"I have done break Download!");stop = true;}/** 取消下载 先将下载线程暂停 然后将本地文件删除*/public void cancelDownload() {Log.e(TAG,"I have done cancel Download!");stop = true;}/** 状态改变 * 这里主要指下载的进度改变监听 */public void onStatusChanged() {long percentage = pogresslength * 100L / totalSize;//Log.d(TAG, "Downloading percentage 2B: " + percentage);if(percentage > 0){if(percentage > currentPercentage){currentPercentage = (int) percentage;// 更新进度条Log.d(TAG, "Downloading percentage: " + currentPercentage + " %(" + filename + ").");}}}public void setTimeout(int timeout){this.timeout = timeout;}/** @param url * 构造方法,传入下载文件的blob url 和下载任务对应的download bean*/public DownloadConnection(String url, int continuteSize) {if(!url.startsWith("http://") && !url.startsWith("https://")){url = "http://" + url;}this.url = url;lastSize = continuteSize;if(buffer == null){buffer = new byte[8 * 1024];}}public void setUrl(String mUrl){url = mUrl;}public String getUrl(){return url;}/** * 依据URL获取文件名当为空时 设置文件名为 default.temp * @param url * @return */private static String getFileNameFromUrl(String url){if(url == null){ // 1url = "default.temp";}else {if(url.lastIndexOf("/") != -1){url = url.substring(url.lastIndexOf("/") + 1, url.length());if(isReg(url)){ // 若有非法字符存在则if(url.lastIndexOf(".") != -1){url = url.substring(url.lastIndexOf(".") + 1, url.length());url = "temp." + url;}else {url = "default.temp";}}}else {if(url.lastIndexOf(".") != -1){url = url.substring(url.lastIndexOf(".") + 1, url.length());url = "temp." + url;}else {url = "default.temp";}}}System.out.println("the file name is " + url);return url;}public static boolean isReg(String code){if(code.contains("/")){return false;}if(code.contains("\\")){ return false;}if(code.contains("[")){return false;}if(code.contains("]")){return false;}if(code.contains("?")){return false;}if(code.contains("<")){return false;}if(code.contains(">")){return false;}if(code.contains("*")){return false;}if(code.contains(":")){return false;}if(code.contains("|")){return false;}if(code.contains("\"")){return false;}return true;}}
转载请注明出处:http://community.csdn.net/
- java源代码详细注释 网络文件下载之分段下载(可扩展 断点续传)
- IOS网络篇17之分段下载、断点续传解析
- java 断点续传网络下载
- java 文件下载 断点续传
- java文件下载断点续传
- Java Web 文件下载之断点续传
- 【Java】之 写个线程下载文件(支持断点续传)
- java文件下载(有非常详细的注释).
- 帮助文档下载(采用大数据量断点续传,分段下载)
- Android文件下载之断点续传
- Winform文件下载之断点续传
- C# 文件下载之断点续传
- java 多线程文件下载,断点续传
- Android网络编程 --断点续传下载文件
- Android实现断点续传下载文件,网络编程
- Android网络编程 --断点续传下载文件
- Android网络编程 --断点续传下载文件
- 断点下载文件(断点续传)
- 散列
- 如何用Android webview播放HTML5 video标签
- UITableViewCell高亮时其子视图的状态修改
- Oracle的取整和四舍五入函数——floor,round,ceil,trunc使用说明
- ArrayList 使用迭代抛出ConcurrentModificationException解决方法
- java源代码详细注释 网络文件下载之分段下载(可扩展 断点续传)
- Android最佳实践之:StrictMode介绍
- UVaOJ 10369 - Arctic Network
- JavaWeb之文件上传
- Android Framework架构浅析之【近期任务】
- Java I/O系统
- Android 异步加载图片
- 浅谈散列
- gcc –finstrument-functions特性的应用