大文件下载断点续传后台功能,仿百度网盘下载功能

最近项目遇到断点续传下载大文件的需求,网上百度了一下,找到了解决方式,感谢大帝的无私奉献。

为了将百度网盘的效果模仿的更逼真,特将原作者的代码完善,写了这篇文章,想为小白省下更多完善代码的时间。

原作者地址我放到文章末尾,废话不多说,直接上代码!


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

/**
 * 断点续传(仿百度网盘下载功能)
 *
 * @author: mj
 * @date: 2022年3月2日14:50:43
 */
public class FileDownLoadUtils {

    public static void main(String[] args) {
        //指定URL
//        String url = "https://mirrors.aliyun.com/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso";
        String url = "https://mirrors.aliyun.com/centos/2/centos2-scripts-v1.tar";
        //下载文件后的本地存储路径
        String downLoadFilePath = "D:\\Download";
        //下载文件
        downLoadFile(url, downLoadFilePath);
    }

    /**
     * 读取目录地址,创建临时文件
     *
     * @param url              文件下载地址
     * @param downLoadFilePath 下载文件本地文件夹存储路径
     */
    private static void downLoadFile(String url, String downLoadFilePath) {
        //临时文件后缀名
        String temp = ".temp";

        try {
            //获取文件路径
            URL uri = new URL(url);
            String filePath = uri.getFile();

            //指定本地下载的目录地址
            File file = new File(downLoadFilePath);
            //生成一个临时文件(目的:主要是记录数据的下标位置(字节长度))
            String tempFilePath = file.getAbsolutePath() + File.separator + filePath.substring(filePath.lastIndexOf("/") + 1) + temp;
            file = new File(tempFilePath);
            //如果目录不存在,则创建
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //将url中的数据流对象,写入到临时文件中file
            writeFile(uri, file);
            //将临时文件重命名为正常文件名
            file.renameTo(new File(tempFilePath.substring(0, tempFilePath.lastIndexOf(temp))));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }

    /**
     * 通过url获取服务器对象流,并写入到文件中file
     *
     * @param uri  文件下载地址
     * @param file 临时文件
     */
    private static void writeFile(URL uri, File file) {

        byte[] bytes = new byte[1024 * 1024];
        //定义流对象
        InputStream inputStream = null;//数据流
        FileOutputStream fileOutputStream = null;//写入file对象数据流
        int byteCount = 0;
        //根据URL和服务器建立连接---数据流
        try {
            fileOutputStream = new FileOutputStream(file, true);
            //建立连接,获取对象流
            inputStream = getInputStream(uri, file.length());

            while ((byteCount = inputStream.read(bytes)) != -1) {
                //数据流---file临时文件中
                fileOutputStream.write(bytes, 0, byteCount);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流对象
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 建立与下载文件的连接,获取下载文件的对象流
     *
     * @param uri             文件下载地址
     * @param startFileLength 临时文件已下载数量
     * @return
     */
    private static InputStream getInputStream(URL uri, long startFileLength) {
        InputStream inputStream = null;
        HttpURLConnection connection;

        try {
//            URL filePath = new URL(url);//和服务器建立连接、获取文件路径
            connection = (HttpURLConnection) uri.openConnection();//开启连接
            connection.setConnectTimeout(3 * 1000);//连接超时时间
            long endFileLength = connection.getContentLengthLong();//文件的总长度
            if (startFileLength < endFileLength) {//还没下载完毕
                connection.disconnect();//销毁链接
                connection = (HttpURLConnection) uri.openConnection();//开启连接
                connection.setConnectTimeout(3 * 1000);//连接超时时间
                connection.setRequestProperty("RANGE", "bytes=" + startFileLength + "-");//设置请求发送下标的对象
                System.out.println(connection.getContentLengthLong());
                inputStream = connection.getInputStream();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return inputStream;
    }

}


原文地址:断点续传(大文件的下载)后台功能实现 - 方大帝的博客 - 博客园
上一篇:unity3d:Assetbundle资源冗余检查输出markdown


下一篇:java两个List的交集,并集