java实现文件续传

原文出自搬砖工,需要转载请注明出处。



        这里给出java实现简单的文件续传的核心代码

        文件存放服务器的代码实现,主要就是想某个文件读出然后传输出去。当然,文件续传肯定是要跳过已下载字节,seek函数就是用来跳过字节的。RandomAccessFile是随机读取文件的类,即支持从某个点开始读取。

public void downloadFileRanges(File downloadFile,RequestContext request,
			ResponseContext response)throws Exception{
		// 要下载的文件大小
		long fileLength = downloadFile.length();
		// 已下载的文件大小
		long pastLength = 0;
		RandomAccessFile raf = null;
		OutputStream os = null;
		OutputStream outPut = null;
		byte b[] = new byte[1024];

		String startRange = request.getHeader("startRange");
		if(!StringUtil.isEmpty(startRange)){//断点存在时
			pastLength = Long.parseLong(startRange);
		}
		String fileName = getDownloadChineseFileName(downloadFile.getName());
		response.setHeader("Content-Disposition",
				"attachment;filename=" + fileName + "");
		// 响应的格式是:
		response.setContentType("application/octet-stream");
		response.addHeader("Content-Length", String.valueOf(fileLength));
		String md5 =FileMd5.getMD5(downloadFile);
		response.setHeader("md5", md5);
		try{
			os = response.getOutputStream();
			outPut = new BufferedOutputStream(os);
			raf = new RandomAccessFile(downloadFile, "r");
			// 跳过已下载字节
			raf.seek(pastLength);

			int n = 0;
			while ((n = raf.read(b, 0, 1024)) != -1) {
				outPut.write(b, 0, n);
			}
			outPut.flush();
		}
		catch (IOException e){//忽略错误
		} 
		finally{
			if(outPut != null){ 
				outPut.close();
			}
			if(raf != null){
				raf.close();
			}
		}
	}

/**
	 * 获取中文名
	 * @param paramName 
	 * @return
	 */
	private String getDownloadChineseFileName(String paramName) {
		String downloadChineseFileName = "";
		try{
			downloadChineseFileName = new String(paramName.getBytes("GBK"),
					"ISO8859-1");
		}
		catch (UnsupportedEncodingException e){
			e.printStackTrace();
		}
		return downloadChineseFileName;
	}
文件下载端核心代码实现,当FileOutputStream设置为true的时候就是从原有文件的地方开始叠加数据。达到续传的目的

public void doDownload(String httpUrl,String saveFileName,String saveFilePath,
			String tarfilename,String tarfilepath,boolean isRange) throws IOException{
		long bytesum = 0;  
		int byteread = 0;
		long bytetotal = 0;
		long size = 0;
		FileOutputStream fs = null;

		String saveFile = saveFilePath+"/"+saveFileName;//saveFilePath文件夹需要存在
		File f = new File(saveFile);
		URL realUrl = new URL(httpUrl); 
		URLConnection conn = realUrl.openConnection();//打开连接
		//设置参数
		if(isRange){//续传则传递开始节点
			size = f.length();
			conn.addRequestProperty("startRange", String.valueOf(size));
		}
		conn.addRequestProperty("filename", tarfilename);
		conn.addRequestProperty("filepath", tarfilepath);

		conn.connect();//建立连接
		InputStream inStream = conn.getInputStream(); 
		String error = conn.getHeaderField("error");
		String MD5 = conn.getHeaderField("MD5");
		if(error!=null){
			return error;
		}
		if(size==0){
			fs = new FileOutputStream(saveFile); 
		}else{
			fs = new FileOutputStream(saveFile,true);  
		}

		bytetotal = conn.getContentLength();
		byte[] buffer = new byte[1024];
		while ((byteread = inStream.read(buffer)) != -1) {  
			bytesum += byteread;//这里可以计算进度
			fs.write(buffer, 0, byteread); 
		}
		fs.close();
	}

当然,续传的过程就是把下载文件已经下载多少传递给文件服务器方,然后文件服务器提供文件流的时候跳过那些字节。然后文件流接受的时候采用叠加方式向文件中写数据。当然为了保证文件的完整性,可以进行文件大小和MD5校验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值