【文件下载】--文件下载的几种方式

最近项目中使用文件的导入和导出功能,临时兴起,网上整理了一下,供自己和需要的朋友参考。

下载不局限于你使用了什么框架,这里我就以spring mvc来演示。

先列出参考的网站:

1.http://rubyq.iteye.com/blog/1408141

2.http://blog.sina.com.cn/s/blog_a261421801019vpi.html

3.http://my.oschina.net/zmf/blog/336961

首先给出全部的代码展示:

1.页面请求

<a href="<%=basePath%>down/down1.do">down1</a> <br />
<a href="<%=basePath%>down/down2.do">down2</a> <br />
<a href="<%=basePath%>down/down3.do">down3</a> <br />
<a href="<%=basePath%>down/down4.do">down4</a> <br />

每个请求都代表着不同的下载方式。

2.后台代码展示:

package XX.XX.OO.OO;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.BufferOverflowException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/down")
public class DownLoadController {

    /**
     * 方法一:以流的形式下载
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/down1.do")
    public void down1(HttpServletRequest request,HttpServletResponse response)throws Exception{
        //事先确定的文件
        String filePath = "E:\springMVC.docx";
        String fileName = "springMVC.docx";
        //读取文件到流中
        File file = new File(filePath);
        InputStream bis = new BufferedInputStream(new FileInputStream(file));
        //把信息放在byte数组中,一次性的放入,该方法适合“小文件下载”
        byte [] temp = new byte[bis.available()];
        bis.read(temp);
        //流用完要关闭
        bis.close();
        //清空response,必须清空
        response.reset();
        //设置response的Header
        response.addHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes()));
        response.addHeader("Content-Length", ""+file.length());
        //很全的设置信息:http://rubyq.iteye.com/blog/1408141
        response.setContentType("application/octet-stream");
        //设置好,输出流
        OutputStream bos = new BufferedOutputStream(response.getOutputStream());
        //输出内容
        bos.write(temp);
        bos.flush();
        bos.close();
    }

    //http://blog.sina.com.cn/s/blog_a261421801019vpi.html
    //http://my.oschina.net/zmf/blog/336961
    /**
     * 下载本地文件
     * @param response
     * @throws Exception
     */
    @RequestMapping("/down2.do")
    public void down2(HttpServletRequest request,HttpServletResponse response) throws Exception{
        //事先确定的文件
        String filePath = "E:\springMVC.docx";
        String fileName = "springMVC.docx";
        InputStream is = new FileInputStream(filePath);
        //设置输出格式
        response.reset();
        response.setContentType("bin");
        response.addHeader("Content-Disposition", "attachment; filename="+fileName.toString());
        //循环取出流中的数据
        byte [] b = new byte[100];
        int len;
        OutputStream os = new BufferedOutputStream(response.getOutputStream());
        while((len=is.read(b))>0){
            os.write(b, 0, len);
        }
        //关闭输出流
        os.close();
        //关闭流入流
        is.close();
    }

    /**
     * 下载网络文件
     * @param response
     * @throws Exception
     */
    @RequestMapping("/down3.do")
    public void down3(HttpServletResponse response) throws Exception{
        //网路下载地址
        String download = "http://pic9.nipic.com/20100910/668573_164813098586_2.jpg";
        //得到下载文件的后缀
        String suffix = download.substring(download.lastIndexOf("."), download.length());
        //URL连接下载
        URL url = new URL(download);
        //打开连接
        URLConnection urlCon =  url.openConnection();
        //得到输入流
        InputStream is = urlCon.getInputStream();
        //下载到地址
        OutputStream os = new FileOutputStream("e:\aa"+suffix);
        //分段下载
        byte [] b = new byte [1024];
        int len;
        //读,读到byte数组中,写,把byte中的数据写到流中
        while((len=is.read(b)) != -1){
            //把b 中的数据写到流中
            os.write(b, 0, len);
            os.flush();
        }
        os.close();
        is.close();
    }


    /**
     * 在线文档打开
     * @param response
     * @throws Exception
     */
    @RequestMapping("/down4.do")
    public void down4(HttpServletResponse response)throws Exception{
        //打开的文件地址
        String filePath = "E:\aa.jpg";
        //String filePath = "E:\springMVC.docx";

        //是否在线打开
        boolean isLine = true;

        //判断文件是否存在
        File f = new File(filePath);
        if(!f.exists()){
            response.sendError(404, "File not Found!");
            System.out.println("文件不存在!");
            return ;
        }

        //读入文件
        InputStream is = new BufferedInputStream(new FileInputStream(f));
        byte [] b = new byte[1024];
        int len;
        //必要设置
        response.reset();//很重要
        //在线打开
        if(isLine){
            //构造在线打开条件
            URL url = new URL("file:///"+filePath);
            response.setContentType(url.openConnection().getContentType());
            response.setHeader("Content-Disposition", "inline; filename="+f.getName());
        }else{
            //下载
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename=" + f.getName());
        }
        //输出流
        OutputStream os = new BufferedOutputStream(response.getOutputStream());
        while((len=is.read(b)) != -1){
            os.write(b,0,len);
            os.flush();
        }
        //关闭
        os.close();
        is.close();
    }
}

上面的请求和Java代码中的对应就可,可以根据自己不同的情况选择不同的实现,还有一种是下载大文件的方式,这里由于没有验证,故没敢贴上,大体看了一下,主要的实现是使用多线程和文件分段传输。以后有空在补上。

原文地址:https://www.cnblogs.com/haoke/p/4552824.html