文件下载之不区分类型大文件的在线下载、传递下载(1请求2,2请求3,1直接得到3的文件)、下载到本地

12 篇文章 0 订阅
9 篇文章 0 订阅

·前言

文件下载有诸多场景,而这一般都涉及到两个部分,一是文件的请求方如何请求,二是文件的提方如何提供。


文件的获取方:

1、直接在浏览器中访问下载地址获取下载文件;

2、使用程序访问下载地址,并将文件保存到指定位置。


文件的提供方:

1、获取本地的文件,比如  d://filePackage//123.zip,对外提供一个请求的下载地址:http://www.localhost:8080/test/test.action;

2、还有一种特殊的文件提供方,直接请求别的地址返回给请求方,是作为中介存在的。准确的说,他自己也是一个文件获取方,比如服务器1上的文件不允许外网访问,服务器2可以访问服务器1同时对外网开放,

用户处于外网想要得到内网服务器1上的文件。这个时候,就需要位于服务器2上的文件提供方从文件服务器1上得到文件并直接返回给外网的请求用户了。


·场景说明

场景说明的一句是下面的代码

1、FileDown.java中有三个方法

fileSupport(),这个方法会把本地文件以流的形式返给请求方,不限制大小,不限制文件格式。可以直接在浏览器访问并下载文件。

如果使用后台java代码访问的话,就会获取到文件流了。

fileDeliver(),这个方法会请求fileSupport()这种提供文件下载的方法,然后再次把文件流返还给请求方,可以这样说,fileDeliver把第一个人的文件传递给了第三个人,也可以直接在浏览器中访问,获得文件。

fileDeliverLocal(),这个方法会把得到的文件流保存到本地指定位置。


2、请求的三个链接

http://localhost:8080/struts2go/fileDown/fileSupport.action

http://localhost:8080/struts2go/fileDown/fileDeliver.action

http://localhost:8080/struts2go/fileDown/fileDeliverLocal.action




·直接贴代码

FileDown.java

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 本类用于测试连续流文件下载
 * 流程是,服务器1提供原始文件,服务器2向服务器1请求,用户请求服务器2得到服务器1中的原始文件,文件格式为zip
 * 本类将提供两个方法
 * fileSupport
 * fileDeliver
 * 
 * 最终实现效果是,用户请求fileDeliver,fileDeliver请求fileSupport,最终用户得到zip文件
 * 
 * java:FileDown.java
 * http://localhost:8080/struts2go/fileDown/fileSupport.action
 * struts:struts-filedown.xml
 * jsp:无
 * @author WuJieJecket
 *
 */
@SuppressWarnings("serial")
public class FileDown extends ActionSupport {
	
	//将本项目中的任意指定文件返回给请求方-无大小限制
	public void fileSupport(){
		
	    String localAddress=ServletActionContext.getServletContext().getRealPath("EpolicyFile");//文件的相对路径,相对于项目的webapp的路径  
	      
	    final String fileName="20151216123456789";//文件的名字  
	    
        try {  
            localAddress = localAddress +"/"+ fileName+ ".zip";//获得zip文件的完整路径
            File file = new File(localAddress); //获得文件
            InputStream ins = new BufferedInputStream(new FileInputStream(file));//获得文件的输入流   

            HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);  
            response.reset();  
            response.addHeader("Content-Disposition","attachment;filename="+new String(file.getName().getBytes()));//设置header,文件名字
            response.addHeader("Content-Length", "" + file.length());  //文件长度
            response.setContentType("application/octet-stream");//设置文件输出类型
            
            OutputStream ous = new BufferedOutputStream(response.getOutputStream());//设置文件输出流  
			
			/*
			 * 该方法对于小文件是可行的,但是对于大型文件则会出现问题
			 * byte[] buffer = new byte[ins.available()]; ins.read(buffer);
			 * ins.close(); ous.write(buffer); ous.flush(); ous.close();
			 */
			
			//适用于大文件的下载,需要注意的是,这里buffer是缓冲区,为了确保下载文件能够正常打开,需要保持为1024的倍数,否则可能造成数据因覆盖重写而损坏
			byte[] buffer = new byte[1024];
			int count = 0;
			while ((count = ins.read(buffer)) > 0) {
				ous.write(buffer, 0, count);
			}
			
			ous.flush();
			ous.close();
			ins.close();

		} catch (Exception e) {
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
		
	}
	
	//请求fileSupport,然后直接把文件流返回给请求fileDeliver的
	public void fileDeliver() throws IOException{
		String getURL="http://localhost:8080/struts2go/fileDown/fileSupport.action";  
		URL getUrl = new URL(getURL);  
		   
		// 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,  
		// 返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection  
		HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();  
		// 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到  
		// 服务器  
		connection.setConnectTimeout(25000);  
		connection.setReadTimeout(25000);  
		connection.connect();  
		  
		int status = connection.getResponseCode();  
		if (status == 200) {  
		DataInputStream ins = new DataInputStream( connection.getInputStream());

			// 将文件流返回给调用本方法的请求
			HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);
			response.reset();

			response.addHeader("Content-Disposition", connection.getHeaderField("Content-Disposition"));// 文件名
			response.addHeader("Content-Length", ""+ connection.getContentLength());// 文件长度
			response.setContentType("application/octet-stream");// 以文件格式不明做出处理方式

			OutputStream ous = new BufferedOutputStream(response.getOutputStream());
			byte[] buffer = new byte[1024];
			int count = 0;
			while ((count = ins.read(buffer)) > 0) {
				ous.write(buffer, 0, count);
			}
			ous.flush();
			ous.close();
			ins.close();

		} else {
			System.out.println("访问异常");
		}
		connection.disconnect();
	}
	
	// 请求fileSupport,然后直接把文件流返回给请求fileDeliver的
	public void fileDeliverLocal() throws IOException {
		String getURL = "http://localhost:8080/struts2go/fileDown/fileSupport.action";//文件下载地址
		String localPath="d:\\a\\";//文件保存的本地地址
		
		URL getUrl = new URL(getURL);

		// 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,
		// 返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection
		HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
		// 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到
		// 服务器
		connection.setConnectTimeout(25000);
		connection.setReadTimeout(25000);
		connection.connect();

		int status = connection.getResponseCode();
		if (status == 200) {
			//获取文件名称
			String fileName=connection.getHeaderField("Content-Disposition").split("=")[1];
			
			DataInputStream ins = new DataInputStream(connection.getInputStream());//获取文件输入流
			
			DataOutputStream ous = new DataOutputStream(new FileOutputStream(localPath+fileName));
			byte[] buffer = new byte[1024];
			int count = 0;
			while ((count = ins.read(buffer)) > 0) {
				ous.write(buffer, 0, count);
			}
			ous.flush();
			ous.close();
			ins.close();

		} else {
			System.out.println("访问异常");
		}
		connection.disconnect();
	}

}

struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
	"http://struts.apache.org/dtds/struts-2.1.7.dtd">
	<struts>
		<!--struts-default-->
		<package name="fileDown" extends="struts-default" namespace="/fileDown">
		<!--
		获得原始下载 
		http://localhost:8080/struts2go/fileDown/fileSupport.action
		-->
		<action name="fileSupport" class="com.demo.fileup.FileDown" method="fileSupport"/>
		
		<!--中介下载,其内部向 http://localhost:8080/struts2go/fileDown fileSupport.action请求 
		http://localhost:8080/struts2go/fileDown/fileDeliver.action
		 -->	
		<action name="fileDeliver" class="com.demo.fileup.FileDown" method="fileDeliver"/>	
		
		<!-- 下载到本地的指定位置 
		http://localhost:8080/struts2go/fileDown/fileDeliverLocal.action
		-->
		<action name="fileDeliverLocal" class="com.demo.fileup.FileDown" method="fileDeliverLocal"/>
		</package>	
	</struts>






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值