Java-文件下载如何实现断点续传

项目合作 项目合作 主题:1030 回复:2135

Java-文件下载如何实现断点续传

浮生未歇 发布于 2017-08-16 字数 79 浏览 1314 回复 3

在java开发环境下,如何实现文件下载断点续传,请大家给些实用的技术方案吧。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

支持 Markdown 语法,需要帮助?

评论(3

想挽留 2017-10-20 3 楼

Java实现断点续传,和其他语言的实现原理都是差不多的,只是针对自己的场景需要做些特殊处理。这里提供一个解决方案,处理中,如果文件存在,则改名下载,不进行覆盖,以免勿删文件。

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

//断点续传
public class DownLoad {

public static void down(String URL, long nPos, String savePathAndFile) {
    try {
        URL url = new URL(URL);
        HttpURLConnection httpConnection = (HttpURLConnection) url
                .openConnection();
        // 设置User-Agent
        httpConnection.setRequestProperty("User-Agent", "NetFox");
        // 设置断点续传的开始位置
        httpConnection.setRequestProperty("RANGE", "bytes=" + nPos);
        // 获得输入流
        InputStream input = httpConnection.getInputStream();
        RandomAccessFile oSavedFile = new RandomAccessFile(savePathAndFile,
                "rw");
        // 定位文件指针到nPos位置
        oSavedFile.seek(nPos);
        byte[] b = new byte[1024];
        int nRead;
        // 从输入流中读入字节流,然后写到文件中
        while ((nRead = input.read(b, 0, 1024)) > 0) {
            (oSavedFile).write(b, 0, nRead);
        }
        httpConnection.disconnect();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static long getRemoteFileSize(String url) {
    long size = 0;
    try {
        HttpURLConnection conn = (HttpURLConnection) (new URL(url))
                .openConnection();
        size = conn.getContentLength();
        conn.disconnect();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return size;
}

public static void main(String[] args) {
String url = "http://www.34ways.com/testfile.flv";
String savePath = "F:\";
String fileName = url.substring(url.lastIndexOf("/"));
String fileNam=fileName;
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) (new URL(url)).openConnection();
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(savePath + fileName);
// 获得远程文件大小
long remoteFileSize = getRemoteFileSize(url);
System.out.println("远程文件大小="+remoteFileSize);
int i = 0;
if (file.exists()) {
// 先看看是否是完整的,完整,换名字,跳出循环,不完整,继续下载
long localFileSize = file.length();
System.out.println("已有文件大小为:"+localFileSize);

        if (localFileSize < remoteFileSize) {
            System.out.println("文件续传");
            down(url, localFileSize, savePath + fileName);
        }else{
            System.out.println("文件存在,重新下载");
            do{
                i++;
                fileName = fileNam.substring(0, fileNam.indexOf(".")) + "(" + i
                        + ")" + fileNam.substring(fileNam.indexOf("."));

                file = new File(savePath + fileName);
            }while(file.exists());
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            down(url, 0, savePath + fileName);
        }
        // 下面表示文件存在,改名字

    } else {
        try {
            file.createNewFile();
            System.out.println("下载中");
            down(url, 0, savePath + fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}}

参考文章(写的很详细,可以看看):
http://www.ibm.com/developerworks/cn/java/joy-down/

虐人心 2017-10-03 2 楼

这里有篇不错的文章,可以参考下。

断点续传和普通下载的不同在于一个是可能从一个文件中间位置下载,而普通下载每次从0开始。所以要支持断点续传,只要能把客户端当前的下载位置告诉服务端,服务端能从客户端需要的位置继续传递数据即可。而这些rfc已经定义好了,遵守这个协议就不会出现大问题。

想挽留 2017-09-07 1 楼

说下基本的原理:
1.首先,获取要下载文件的长度和头信息等文件信息,并对文件头信息作出相应相应信息。
2.下载开始,获取文件的输入流,将文件分割为若干的“块”,块的大小自己决定,每一块都单独去存储,写入。
3.记录写入的文件指针位置,这样,如果网络断开,下次下载的时候,就可以通过指针的位置来继续上次的位置开始下载了
具体代码实现,网上一搜一大把,就不赘述了