`

断点续传和分段上传

 
阅读更多
package com.test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
 * 文件断点续传加分段上传线程
 * @author wzztestin
 *
 */
public class DownFileFetch extends Thread {
	DownFileInfoBean siteInfoBean = null; // 文件信息 Bean
	long[] nStartPos; // 开始位置
	long[] nEndPos; // 结束位置
	FileSplitterFetch[] fileSplitterFetch; // 子线程对象
	long nFileLength; // 文件长度
	boolean bFirst = true; // 是否第一次取文件
	boolean bStop = false; // 停止标志
	File tmpFile; // 文件下载的临时信息
	DataOutputStream output; // 输出到文件的输出流
	boolean fileflag;
	String downfile;

	public DownFileFetch(DownFileInfoBean bean) throws IOException {
		siteInfoBean = bean;
		//File.separator windows是\,unix是/
		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()];
		}
		fileflag = bean.getFileflag();
		downfile = bean.getFilepath();
	}

	public void run() {
		// 获得文件长度
		// 分割文件
		// 实例 FileSplitterFetch
		// 启动 FileSplitterFetch 线程
		// 等待子线程返回
		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[i] = (long) (i * (nFileLength / nStartPos.length));
					}
					for (int i = 0; i < nEndPos.length - 1; i++) {
						nEndPos[i] = nStartPos[i + 1];
					}
					nEndPos[nEndPos.length - 1] = nFileLength;
				}
			}
			// 启动子线程
			fileSplitterFetch = new FileSplitterFetch[nStartPos.length];
			for (int i = 0; i < nStartPos.length; i++) {
				fileSplitterFetch[i] = new FileSplitterFetch(
						siteInfoBean.getSSiteURL(), siteInfoBean.getSFilePath()
								+ File.separator + siteInfoBean.getSFileName(),
						nStartPos[i], nEndPos[i], i,fileflag,downfile);
				FileUtility.log("Thread " + i + " , nStartPos = " + nStartPos[i]
						+ ", nEndPos = " + nEndPos[i]);
				fileSplitterFetch[i].start();
			}
			// fileSplitterFetch[nPos.length-1] = new
			// FileSplitterFetch(siteInfoBean.getSSiteURL(),siteInfoBean.getSFilePath()
			// + File.separator +
			// siteInfoBean.getSFileName(),nPos[nPos.length-1],nFileLength,nPos.length-1);
			// FileUtility.log("Thread " +(nPos.length-1) +
			// ",nStartPos = "+nPos[nPos.length-1]+",nEndPos = " + nFileLength);
			// fileSplitterFetch[nPos.length-1].start();
			// 等待子线程结束
			// int count = 0;
			// 是否结束 while 循环
			boolean breakWhile = false;
			while (!bStop) {
				write_nPos();
				FileUtility.sleep(500);
				breakWhile = true;
				for (int i = 0; i < nStartPos.length; i++) {
					if (!fileSplitterFetch[i].bDownOver) {
						breakWhile = false;
						break;
					}
				}
				if (breakWhile)
					break;
				// count++;
				// if(count>4)
				// siteStop();
			}
			System.err.println("文件下载结束!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	} // 获得文件长度

	public long getFileSize() {
		int nFileLength = -1;
		if(fileflag){
			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 ());
					// FileUtility.log(in.readLine());
					sHeader = httpConnection.getHeaderFieldKey(i);
					if (sHeader != null) {
						if (sHeader.equals("Content-Length")) {
							nFileLength = Integer.parseInt(httpConnection
									.getHeaderField(sHeader));
							break;
						}
					} else
						break;
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
			FileUtility.log(nFileLength);
		}else{
			try{
				File myflie = new File(downfile);
				nFileLength = (int)myflie.length();
			}catch(Exception e){
				e.printStackTrace();
			}
			FileUtility.log(nFileLength);
		}
		return nFileLength;
	}

	// 保存下载信息(文件指针位置)
	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[i]);
				output.writeLong(fileSplitterFetch[i].nStartPos);
				output.writeLong(fileSplitterFetch[i].nEndPos);
			}
			output.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 读取保存的下载信息(文件指针位置)
	private void read_nPos() {
		try {
			DataInputStream input = new DataInputStream(new FileInputStream(
					tmpFile));
			int nCount = input.readInt();
			nStartPos = new long[nCount];
			nEndPos = new long[nCount];
			for (int i = 0; i < nStartPos.length; i++) {
				nStartPos[i] = input.readLong();
				nEndPos[i] = 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);
	}

	// 停止文件下载
	public void siteStop() {
		bStop = true;
		for (int i = 0; i < nStartPos.length; i++)
			fileSplitterFetch[i].splitterStop();
	}
}

 

package com.test;

import java.io.*;
import java.net.*;
/**
 * 下载上传子线程
 * @author wzztestin
 *
 */
public class FileSplitterFetch extends Thread {
	String sURL; // 下载文件的地址
	long nStartPos; // 文件分段的开始位置
	long nEndPos; // 文件分段的结束位置
	int nThreadID; // 线程的 ID
	boolean bDownOver = false; // 是否下载完成
	boolean bStop = false; // 停止下载
	FileAccess fileAccessI = null; // 文件对象
	boolean fileflag; //是URL下载还是本地下载
	File file = null;//本地下载文件

	public FileSplitterFetch(String sURL, String sName, long nStart, long nEnd,
			int id,boolean fileflag,String filepath) throws IOException {
		this.sURL = sURL;
		this.nStartPos = nStart;
		this.nEndPos = nEnd;
		nThreadID = id;
		fileAccessI = new FileAccess(sName, nStartPos);
		this.fileflag = fileflag;
		if(filepath != null){
			this.file = new File(filepath);
		}
	}

	public void run() {
		if(fileflag){
			this.urldownload();
		}else{
			this.filedownload();
		}
	}

	// 打印回应的头信息
	public void logResponseHead(HttpURLConnection con) {
		for (int i = 1;; i++) {
			String header = con.getHeaderFieldKey(i);
			if (header != null)
				// responseHeaders.put(header,httpConnection.getHeaderField(header));
				FileUtility.log(header + " : " + con.getHeaderField(header));
			else
				break;
		}
	}
	
	/**
	 * 地址下载
	 */
	private void urldownload(){
		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);
				FileUtility.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 += fileAccessI.write(b, 0, nRead);
					// if(nThreadID == 1)
					// FileUtility.log("nStartPos = " + nStartPos + ", nEndPos = " +
					// nEndPos);
				}
				FileUtility.log("Thread " + nThreadID + " is over!");
				bDownOver = true;
				// nPos = fileAccessI.write (b,0,nRead);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 文件下载
	 */
	private void filedownload(){
		while (nStartPos < nEndPos && !bStop) {
			try {
				InputStream input = new FileInputStream(file);
				input.skip(nStartPos);
				byte[] b = new byte[1024];
				int nRead;
				while ((nRead = input.read(b, 0, 1024)) > 0
						&& nStartPos < nEndPos && !bStop) {
					nStartPos += fileAccessI.write(b, 0, nRead);
				}
				FileUtility.log("Thread " + nThreadID + " is over!");
				bDownOver = true;
				input.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void splitterStop() {
		bStop = true;
	}
}

 

package com.test;

/**
 * 简单的工具类
 * @author wzztestin
 *
 */
public class FileUtility {
	public FileUtility() {
	}

	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);
	}
}

 

package com.test;

public class DownFileInfoBean {
	private String sSiteURL; // 文件的下载地址
	private String sFilePath; // 保存文件的路径
	private String sFileName; // 保存文件的名字
	private int nSplitter; // 文件分成几段,默认是5段
	private boolean fileflag; // 如果为FALSE则是本地下载,为TRUE则URL下载
	private String filepath;

	public String getFilepath() {
		return filepath;
	}

	public void setFilepath(String filepath) {
		this.filepath = filepath;
	}

	public boolean getFileflag() {
		return fileflag;
	}

	public void setFileflag(boolean fileflag) {
		this.fileflag = fileflag;
	}

	public DownFileInfoBean() {
		// default 5
		this("", "", "", 5,false,null);
	}

	public DownFileInfoBean(String sURL, String sPath, String sName, int nSpiltter,boolean fileflag,String filepath) {
		sSiteURL = sURL;
		sFilePath = sPath;
		sFileName = sName;
		this.nSplitter = nSpiltter;
		this.fileflag = fileflag;
		this.filepath = filepath;
	}

	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;
	}
}

 

package com.test;

import java.io.*;

public class FileAccess implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2518013155676212866L;
	RandomAccessFile oSavedFile;
	long nPos;

	public FileAccess() throws IOException {
		this("", 0);
	}

	public FileAccess(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;
	}
}

 

package com.test;

/**
 * 测试类
 * @author wzztestin
 *
 */
public class TestMethod {
	public TestMethod() {
		try {
			/*DownFileInfoBean bean = new DownFileInfoBean(
					"http://cdn.market.hiapk.com/data/upload//2012/09_27/17/car.wu.wei.kyo.shandian_174928.apk", "D:\\temp",
					"shandian_174928.apk", 5,true,null);*/
			DownFileInfoBean bean = new DownFileInfoBean(null, "D:\\temp",
					"F-A2_20130923.apk", 10,false,"D:\\fengye-MA2013091200102_F-A2_20130923.apk");
			DownFileFetch fileFetch = new DownFileFetch(bean);
			fileFetch.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new TestMethod();
	}
}

 

分享到:
评论

相关推荐

    漫画作品与时间旅行题材.doc

    漫画作品与时间旅行题材

    基于SpringBoot框架的的在线视频教育平台的设计与实现(含完整源码+完整毕设文档+PPT+数据库文件).zip

    Spring Boot特点: 1、创建一个单独的Spring应用程序; 2、嵌入式Tomcat,无需部署WAR文件; 3、简化Maven配置; 4、自动配置Spring; 5、提供生产就绪功能,如指标,健康检查和外部配置; 6、绝对没有代码生成和XML的配置要求;第一章 绪 论 1 1.1背景及意义 1 1.2国内外研究概况 2 1.3 研究的内容 2 第二章 关键技术的研究 3 2.1 相关技术 3 2.2 Java技术 3 2.3 ECLIPSE 开发环境 4 2.4 Tomcat介绍 4 2.5 Spring Boot框架 5 第三章 系统分析 5 3.1 系统设计目标 6 3.2 系统可行性分析 6 3.3 系统功能分析和描述 7 3.4系统UML用例分析 8 3.4.1管理员用例 9 3.4.2用户用例 9 3.5系统流程分析 10 3.5.1添加信息流程 11 3.5.2操作流程 12 3.5.3删除信息流程 13 第四章 系统设计 14 4.1 系统体系结构 15 4.2 数据库设计原则 16 4.3 数据表 17 第五章 系统实现 18 5.1用户功能模块 18 5.2

    PyTorch入门指南:从零开始掌握深度学习框架.pdf

    内容概要:本文作为PyTorch的入门指南,首先介绍了PyTorch相较于TensorFlow的优势——动态计算图、自动微分和丰富API。接着讲解了环境搭建、PyTorch核心组件如张量(Tensor)、autograd模块以及神经网络的定义方式(如nn.Module),并且给出了详细的神经网络训练流程,包括前向传播、计算损失值、进行反向传播以计算梯度,最终调整权重参数。此外还简要提及了一些拓展资源以便进一步探索这个深度学习工具。 适用人群:初次接触深度学习技术的新学者和技术爱好者,有一定程序基础并希望通过PyTorch深入理解机器学习算法实现的人。 使用场景及目标:该文档有助于建立使用者对于深度学习及其具体实践有更加直观的理解,在完成本教程之后,读者应当能够在个人设备上正确部署Python环境,并依据指示独立创建自己的简易深度学习项目。 其他说明:文中所提及的所有示例均可被完整重现,同时官方提供的资料链接也可以方便有兴趣的人士对感兴趣之处继续挖掘,这不仅加深了对PyTorch本身的熟悉程度,也为未来的研究或者工程项目打下了良好的理论基础和实践经验。

    古镇美食自驾游:舌尖上的历史韵味.doc

    古镇美食自驾游:舌尖上的历史韵味

    基于人工神经网络(ANN)的高斯白噪声的系统识别 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    漫画作品与神话传说融合.doc

    漫画作品与神话传说融合

    实时电价机制下交直流混合微网优化运行方法 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    ADC推理软件AI程序

    ADC推理软件AI程序

    漫画作品与科幻元素融合.doc

    漫画作品与科幻元素融合

    【电缆】中压电缆局部放电的传输模型研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    基于人工神经网络的类噪声环境声音声学识别 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    多约束、多车辆VRP问题 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    基于麻雀搜索算法(SSA)优化长短期记忆神经网络参数SSA-LSTM冷、热、电负荷预测 附Python代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    java-springboot+vue景区民宿预约系统实现源码(完整前后端+mysql+说明文档+LunW+PPT).zip

    java-springboot+vue景区民宿预约系统实现源码(完整前后端+mysql+说明文档+LunW+PPT).zip

    56页-智慧园区解决方案(伟景行).pdf

    在智慧城市建设的大潮中,智慧园区作为其中的璀璨明珠,正以其独特的魅力引领着产业园区的新一轮变革。想象一下,一个集绿色、高端、智能、创新于一体的未来园区,它不仅融合了科技研发、商业居住、办公文创等多种功能,更通过深度应用信息技术,实现了从传统到智慧的华丽转身。 智慧园区通过“四化”建设——即园区运营精细化、园区体验智能化、园区服务专业化和园区设施信息化,彻底颠覆了传统园区的管理模式。在这里,基础设施的数据收集与分析让管理变得更加主动和高效,从温湿度监控到烟雾报警,从消防水箱液位监测到消防栓防盗水装置,每一处细节都彰显着智能的力量。而远程抄表、空调和变配电的智能化管控,更是在节能降耗的同时,极大地提升了园区的运维效率。更令人兴奋的是,通过智慧监控、人流统计和自动访客系统等高科技手段,园区的安全防范能力得到了质的飞跃,让每一位入驻企业和个人都能享受到“拎包入住”般的便捷与安心。 更令人瞩目的是,智慧园区还构建了集信息服务、企业服务、物业服务于一体的综合服务体系。无论是通过园区门户进行信息查询、投诉反馈,还是享受便捷的电商服务、法律咨询和融资支持,亦或是利用云ERP和云OA系统提升企业的管理水平和运营效率,智慧园区都以其全面、专业、高效的服务,为企业的发展插上了腾飞的翅膀。而这一切的背后,是大数据、云计算、人工智能等前沿技术的深度融合与应用,它们如同智慧的大脑,让园区的管理和服务变得更加聪明、更加贴心。走进智慧园区,就像踏入了一个充满无限可能的未来世界,这里不仅有科技的魅力,更有生活的温度,让人不禁对未来充满了无限的憧憬与期待。

    边境自驾游异国风情深度体验.doc

    边境自驾游异国风情深度体验

    武汉东湖高新集团智慧园区 22页PPT(21页).pptx

    在智慧城市建设的大潮中,智慧园区作为其中的璀璨明珠,正以其独特的魅力引领着产业园区的新一轮变革。想象一下,一个集绿色、高端、智能、创新于一体的未来园区,它不仅融合了科技研发、商业居住、办公文创等多种功能,更通过深度应用信息技术,实现了从传统到智慧的华丽转身。 智慧园区通过“四化”建设——即园区运营精细化、园区体验智能化、园区服务专业化和园区设施信息化,彻底颠覆了传统园区的管理模式。在这里,基础设施的数据收集与分析让管理变得更加主动和高效,从温湿度监控到烟雾报警,从消防水箱液位监测到消防栓防盗水装置,每一处细节都彰显着智能的力量。而远程抄表、空调和变配电的智能化管控,更是在节能降耗的同时,极大地提升了园区的运维效率。更令人兴奋的是,通过智慧监控、人流统计和自动访客系统等高科技手段,园区的安全防范能力得到了质的飞跃,让每一位入驻企业和个人都能享受到“拎包入住”般的便捷与安心。 更令人瞩目的是,智慧园区还构建了集信息服务、企业服务、物业服务于一体的综合服务体系。无论是通过园区门户进行信息查询、投诉反馈,还是享受便捷的电商服务、法律咨询和融资支持,亦或是利用云ERP和云OA系统提升企业的管理水平和运营效率,智慧园区都以其全面、专业、高效的服务,为企业的发展插上了腾飞的翅膀。而这一切的背后,是大数据、云计算、人工智能等前沿技术的深度融合与应用,它们如同智慧的大脑,让园区的管理和服务变得更加聪明、更加贴心。走进智慧园区,就像踏入了一个充满无限可能的未来世界,这里不仅有科技的魅力,更有生活的温度,让人不禁对未来充满了无限的憧憬与期待。

    ,,CAD、DXF导图,自动进行位置路径规划,源码可进行简单功能添加实现设备所需功能,已经在冲孔机,点胶机上应用,性价比超高 打孔机实测一分钟1400个孔 ,CAD、DXF导图;自动位置路径规划;源

    ,,CAD、DXF导图,自动进行位置路径规划,源码可进行简单功能添加实现设备所需功能,已经在冲孔机,点胶机上应用,性价比超高。 打孔机实测一分钟1400个孔 ,CAD、DXF导图;自动位置路径规划;源码功能添加;设备功能实现;冲孔机点胶机应用;高性价比。,CAD导图DXF,自动规划位置路径,实测打孔速度惊人!性价比超高冲孔机实现多功能定制

    一种鲁棒的可变功率分数LMS算法研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    本地部署,LM Studio,可以让大家本地部署在自己家里的电脑deepseek,再也不用忍受网站上deepseek的服务器繁忙的烦恼

    本地部署,LM Studio,可以让大家本地部署在自己家里的电脑deepseek,再也不用忍受网站上deepseek的服务器繁忙的烦恼

Global site tag (gtag.js) - Google Analytics