java 通过URL下载文件或图片到本地

需求:

支持文件批量下载。

使用JS能够实现批量下载,能够提供接口从指定url中下载文件并保存在本地指定路径中。

服务器不需要打包。

支持大文件断点下载。比如下载10G的文件。

PC端全平台支持。Windows,macOS,Linux

全浏览器支持。ie6,ie7,ie8,ie9,ie10,ie11,edge,firefox,chrome,safari

支持文件夹结构下载。不希望在服务器打包,而是直接下载文件夹,下载后在本地文件夹结构和服务器保持一致。

 

简单的后台代码实现。

//注意!本人为linux系统没有盘符. 

File file=new File(“/home/.后面省略”);//此为绝对路径 

File file=new File(“../workspace/后面省略”)//此为相对路径 

FileOutputStream out =new FileOutputStream(file);//要输出到的本地文件路径 

URL url=new URL(“http://xxxxxxxxx”); 

URLConnection conn=url.openConnection(); 

InputStream is=conn.getInputStream(); 

byte[] data =new byte[1024]; 

int len=0; 

//也可以先写道字节数组输出流,在一次性的用文件输出流输出 

//ByteArrayOutputStream bos=new ByteArrayOutputStream(); 

while((len=is.read(data))!=-1) 

{ 

    out.write(data,0,len);//将数据通过输出流输出到本地. 

    /*

        //如果是用字节数组的话     

        bos.write(data,0,len);

    */

} 

/*

//如果是用字节数组的话

byte[] data2=bos.toByteArray();

out.write(data2);

*/ 

out.close(); 

is.close(); 

 

服务端下载代码

支持断点续传

支持分片

支持迅雷等基于HTTP协议的下载软件

<%@page language=“java” import=“java.util.*” pageEncoding=“UTF-8”%>

<%@page contentType=“text/html;charset=UTF-8”%>

<%@page import=“down2.*” %>

<%@page import=“java.net.URLDecoder” %>

<%@page import=“java.net.URLEncoder” %>

<%@page import=“org.apache.commons.lang.*” %>

<%@page import=“com.google.gson.FieldNamingPolicy” %>

<%@page import=“com.google.gson.Gson” %>

<%@page import=“com.google.gson.GsonBuilder” %>

<%@page import=“com.google.gson.annotations.SerializedName” %>

<%@page import=“java.io.*” %>

<% out.clear();

/*

    下载数据库中的文件。

    更新记录:

        2015-05-13 创建

        2017-12-09 完善Range协议

*/

String fileName = 网易云音乐.exe”;//客户端保存的文件名

String filePath = “d:\\文件校验工具.exe”;//路径

 

fileName = URLEncoder.encode(fileName,“UTF-8”);

fileName = fileName.replaceAll(“\\+”,“%20”);

response.setContentType(“application/octet-stream;charset:utf-8”);

response.addHeader(“Content-Disposition”,“attachment;filename=” + fileName);

response.addHeader(“Pragma”“No-cache”);

response.addHeader(“Cache-Control”“No-cache”);

response.addHeader(“Expires”“0”);

 

//定位文件块索引

File f = new File(filePath);

long fileLen = f.length();

long blockSize = fileLen;//块大小

long blockBegin = 0;

long blockEnd = 0;

RandomAccessFile raf = new RandomAccessFile(filePath,“r”);

FileInputStream in = new FileInputStream( raf.getFD() );

String range = request.getHeader(“Range”);

if(range != null)

{

    //清除bytes=

    int pos = range.indexOf(“=”);

    if(pos != -1) range = range.substring(pos+1);

   

    /*

        1-

        -1

        0-1

    */

    String[] rs = range.split(“-“);//bytes=10254

    //-1

    if( StringUtils.isEmpty(rs[0]) )

    {

        blockSize = Long.parseLong(rs[1]);

        in.skip(fileLen – blockSize);

        blockEnd = fileLen – 1;

        blockBegin = fileLen – blockSize;

    }//1-

    elseif( StringUtils.isEmpty(rs[1]))

    {

        blockBegin = Long.parseLong(rs[0]);

        in.skip(blockBegin);

        blockSize = fileLen – blockBegin;

        blockEnd = (blockBegin + blockSize) – 1;

    }//1-1

    else

    {

        blockBegin = Long.parseLong(rs[0]);

        blockEnd = Long.parseLong(rs[1]);

        blockSize = (blockEnd – blockBegin) + 1;

        in.skip(blockBegin);

    }

}

response.addHeader(“Content-Length”,Long.toString(blockSize));

response.addHeader(“Content-Range”,String.format(“bytes %d-%d/%d”,blockBegin,blockEnd,fileLen) );

 

byte[] b = newbyte[1048576];//一次读1MB数据,如果服务器内存足够,可适当调大尺寸。

int i = 0;

 

OutputStream outp = response.getOutputStream();

while((i = in.read(b)) > 0)

{

    outp.write(b, 0, i);

}

outp.flush();

 

in.close();

outp.close();

in  = null;

outp = null;

%>

 

js代码批量下载。

$(“#btn-down-files”).click(function () {

    if (downer.Config[“Folder”] == “”) { downer.open_folder(); return; }

    var urls = [

        { fileUrl: “http://res2.ncmem.com/res/images/ie11.png” }

        , { fileUrl: “http://res2.ncmem.com/res/images/up6.1/down.png” }

        , { fileUrl: “http://res2.ncmem.com/res/images/firefox.png” }

        , { fileUrl: “http://res2.ncmem.com/res/images/edge.png” }

        , { fileUrl: “http://res2.ncmem.com/res/images/up6.1/cloud.png” }

        , { fileUrl: “http://res2.ncmem.com/res/images/home/w.png” }

        , { fileUrl: “http://res2.ncmem.com/res/images/img.png” }

    ];

    downer.app.addUrls(urls);

});

 

html引入头文件

<head>

    <metahttp-equiv=“Content-Type” content=“text/html; charset=utf-8” />

    <title>donw2-多文件演示页面</title>

    <linktype=“text/css” href=“js/down.css” rel=“Stylesheet” />

    <scripttype=“text/javascript” src=“js/jquery-1.4.min.js”></script>

    <scripttype=“text/javascript” src=“js/down.app.js” charset=“utf-8”></script>

    <scripttype=“text/javascript” src=“js/down.edge.js” charset=“utf-8”></script>

    <scripttype=“text/javascript” src=“js/down.file.js” charset=“utf-8”></script>

    <scripttype=“text/javascript” src=“js/down.folder.js” charset=“utf-8”></script>

    <scripttype=“text/javascript” src=“js/down.js” charset=“utf-8”></script>

</head>

 

效果:

 

网上例子:http://blog.ncmem.com/wordpress/2019/08/28/java批量下载/