Tips:Java 文件断点下载 【送源码】

Ray 源码分析系列(2)—编译 Ray能被OpenAI、微信、字节等大厂采用,必定有其独特优势,这个系列的文章将会深入分析Ray的绝大部分核心代码。 阅读详情

前言

❝

互联网的连接速度慢且不稳定,有可能由于网络故障导致断开连接。

在客户端下载一个大对象时,因网络断开导致上传下载失败的概率就会变得不可忽视。

❞

图片

客户端在GET对象请求时通过设置Range头部来告诉接口服务需要从什么位置开始输出对象的数据。

判断是否支持断点下载,根据文档:14.35.1 Byte Rangeshttps://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

// 直接判断是否有 Accept-Ranges = bytes
boolean support = urlConnection.getHeaderField("Accept-Ranges").equals("bytes");
System.out.println("Partial content retrieval support = " + (support ? "Yes" : "No));

例如:

donald@donald-pro:~$ curl -i --range 0-9 http://localhost:8080/file/chunk/download
HTTP/1.1 206
Accept-Ranges: bytes
Content-Disposition: inline;filename=pom.xml
Content-Range: bytes 0-9/13485
Content-Length: 10
Date: Mon, 01 Nov 2021 09:53:25 GMT

直接判断头部 HEAD,例如:

❝

HeadObject 接口用于获取某个文件(Object)的元信息。使用此接口不会返回文件内容。

❞

HEAD /ObjectName HTTP/1.1
Host: BucketName.oss-cn-hangzhou.aliyuncs.com
Date: GMT Date
Authorization: SignatureValue

需知,对应 HTTP 状态码:

  • 206 Partial Content:HTTP Range 请求成功

  • 416 Requested Range Not Satisfiable status:HTTP Range 请求超出界限

  • 200 OK:不支持范围请求

小结如下:

  1. HTTP 范围请求:需要 HTTP/1.1 及之上支持,如果双端某一段低于此版本,则认为不支持。

  2. 通过响应头中的 Accept-Ranges 来确定是否支持范围请求。

  3. 通过在请求头中添加 Range 这个请求头,来指定请求的内容实体的字节范围。

  4. 在响应头中,通过 Content-Range 来标识当前返回的内容实体范围,并使用 Content-Length 来标识当前返回的内容实体范围长度。

  5. 在请求过程中,可以通过 If-Range 来区分资源文件是否变动,它的值来自 ETag 或者 Last-Modifled。如果资源文件有改动,会重新走下载流程。

生产实战

开发也得依靠依据,设定好边界,才能掌控全局。

有现成的文档,来看阿里云文档https://help.aliyun.com/document_detail/39571.html

  • Range: bytes=0-499:表示第0~499字节范围的内容。

  • Range: bytes=500-999:表示第500~999字节范围的内容。

  • Range: bytes=-500:表示最后500字节的内容。

  • Range: bytes=500-:表示从第500字节开始到文件结束部分的内容。

  • Range: bytes=0-:表示第一个字节到最后一个字节,即完整的文件内容。微信搜索公众号:Java后端编程,回复:java 领取资料 。

HTTP Range 是否合法对应处理:

  • 如果 HTTP Range 请求合法,响应返回值为 206 并在响应头中包含 Content-Range

  • 如果 HTTP Range 请求不合法,或者指定范围不在有效区间,会导致 Range 不生效,响应返回值为200,并传送整个 Object 内容。

❝

如下为 HTTP Range 请求不合法的示例及错误说明: 假设 Object 资源大小为1000字节,Range 有效区间为0~999

  • Range: byte=0-499:格式错误,byte 应为 bytes。

  • Range: bytes=0-1000:末字节 1000 超出有效区间。

  • Range: bytes=1000-2000:指定范围超出有效区间。

  • Range: bytes=1000-:首字节超出有效区间。

  • Range: bytes=-2000:指定范围超出有效区间。

❞

举一些栗子:

# 正常范围下载
donald@donald-pro:~$ curl -i --range 0-9 http://localhost:8080/file/chunk/download
HTTP/1.1 206 
Accept-Ranges: bytes
Content-Disposition: inline;filename=Screen_Recording_20211101-162729_Settings.mp4
Content-Range: bytes 0-9
Content-Type: application/force-download;charset=UTF-8
Content-Length: 16241985
Date: Wed, 03 Nov 2021 09:50:50 GMT

服务端 - 业务开发

这里以 SpringBoot 为栗子:

  1. 对外支持 range 下载

  2. 底层存储:使用 ceph

  3. Controller 如下:

@Slf4j
@RestController
public class Controller {
    @Autowired
    private FileService fileService;
    
    /**
     * 下载文件
     *
     * 对外提供
     *
     * @param fileId 文件Id
     * @param token token
     * @param accountId 帐号Id
     * @param response 响应
     */
    @GetMapping("/oceanfile/download")
    public void downloadOceanfile(@RequestParam String fileId,
                                  @RequestHeader(value = "Range") String range,
                                  HttpServletResponse response) {

        this.fileService.downloadFile(fileId, response, range);
    }
}
  1. Service 如下:

@Slf4j
@Service
public class FileService {
    @Autowired
    private CephUtils cephUtils;
    
    /**
     * 直接下载文件
     *
     * Tips: 支持断点下载
     * @param fileId 文件Id
     * @param response 返回
     * @param range 范围
     */
    public void downloadFile(String fileId, HttpServletResponse response, String range) {
        // 根据 fileId 获取文件信息
        FileInfo fileInfo = getFileInfo(fileId);

        String bucketName = fileInfo.getBucketName();
        String relativePath = fileInfo.getRelativePath();

        // 处理 range,范围信息
        RangeDTO rangeInfo = executeRangeInfo(range, fileInfo.getFileSize());

        // rangeInfo = null,直接下载整个文件
        if (Objects.isNull(rangeInfo)) {
        
            cephUtils.downloadFile(response, bucketName, relativePath);
            return;
        }
        // 下载部分文件
        cephUtils.downloadFileWithRange(response, bucketName, relativePath, rangeInfo);
    }

    private RangeDTO executeRangeInfo(String range, Long fileSize) {

        if (StringUtils.isEmpty(range) || !range.contains("bytes=") || !range.contains("-")) {

            return null;
        }

        long startByte = 0;
        long endByte = fileSize - 1;

        range = range.substring(range.lastIndexOf("=") + 1).trim();
        String[] ranges = range.split("-");

        if (ranges.length <= 0 || ranges.length > 2) {

            return null;
        }

        try {
            if (ranges.length == 1) {
                if (range.startsWith("-")) {

                    //1. 如:bytes=-1024  从开始字节到第1024个字节的数据
                    endByte = Long.parseLong(ranges[0]);
                } else if (range.endsWith("-")) {

                    //2. 如:bytes=1024-  第1024个字节到最后字节的数据
                    startByte = Long.parseLong(ranges[0]);
                }
            } else {
                //3. 如:bytes=1024-2048  第1024个字节到2048个字节的数据
                startByte = Long.parseLong(ranges[0]);
                endByte = Long.parseLong(ranges[1]);
            }
        } catch (NumberFormatException e) {
            startByte = 0;
            endByte = fileSize - 1;
        }
        
        if (startByte >= fileSize) {
            
            log.error("range error, startByte >= fileSize. " +
                    "startByte: {}, fileSize: {}", startByte, fileSize);
            return null;
        }

        return new RangeDTO(startByte, endByte);
    }
}

以上内容,大家可以收藏起来,如果以后遇到这样的场景,分分钟搞定!

   - EOF -

 给大家分享一套基于Springboot+Vue的停车场管理系统源码,在实际项目中可以直接复用。(免费提供,文末自取)

一、系统运行图

1、登陆页面

2、车位管理

3、车辆进出管理

二、系统搭建视频教程

源码免费领取方式

后台回复  停车场

用SOEM库搞定汇川SV660N伺服电机:一个Linux C程序员的EtherCAT实战笔记 本文详细介绍了如何在Linux系统下使用SOEM库驱动汇川SV660N伺服电机,包括环境搭建、EtherCAT从站设备识别、PDO映射配置、状态机切换与运动控制等关键步骤。通过实战代码示例和常见问题排查指南,帮助开发者快速掌握工业自动化中的EtherCAT通信技术,实现对伺服电机的精准控制。 阅读详情

相关推荐

FPGA远程升级避坑实录:用STARTUPE2原语搞定Flash时钟,K7325T实测有效

本文深入解析了FPGA远程升级中的STARTUPE2原语应用,特别针对K7325T芯片的Flash时钟问题提供了实测有效的解决方案。通过详细的原语工作机制、Vivado工程实现步骤及调试技巧,帮助工程师规避常见陷阱,提升远程升级的可靠性和效率。

weixin_42558093的博客 142

Java-断点下载(分片下载)

介绍 当下载一个很大的文件时,如果下载到一半暂停,如果继续下载呢?断点下载就是解决这个问题的。 具体原理: 利用indexedDb,将下载的数据存储到用户的本地中,这样用户就算是关电脑那么下次下载还是从上次的位置开始的 先去看看本地缓存中是否存在这个文件的分片数据,如果存在那么就接着上一个分片继续下载(起始位置) 下载前先去后端拿文件的大小,然后计算分多少次下载(n/(1024*1024*10)) (结束位置) 每次下载的数据放入一个Blob中,然后存储到本地indexedDB 当全部下载完毕后,将所有

weixin_45203607的博客 5743

大模型选型实战:为OpenClaw匹配最优“大脑”的全维度考量

大模型不是越贵越好,也不是参数越高越好,适合自己的使用场景才是最好的。按照我的方法,先明确自己的需求,再选对应的模型,配置多模型自动路由,既能保证体验,又能最大限度降低成本。我自己用这套配置用了半年多,不管是写文章、写代码还是处理复杂问题,都完全够用,成本也很低,大家可以参考一下。如果不知道选什么模型,可以在评论区说一下你的使用场景。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 343

Java实战:Spring Boot 实现文件断点下载

本文将详细介绍如何在 Spring Boot 应用程序中实现文件断点下载功能。我们将深入探讨 HTTP 协议中的 Range 请求头以及如何使用 Spring Boot 中的 `ResponseEntity` 和 `HttpHeaders` 类来支持断点下载。

oandy0的博客 2782

AI 大模型接口太零散?自建私有模型管理平台统一整合,管理使用超方便!(支持飞牛nas、群晖nas等服务器快速部署)

面对多种 AI 大模型接口难统一、管理繁琐的问题🤯,本文分享一款超实用开源网关工具⚡,可聚合各大模型、自动转接口、支持可视化管理,Docker 一键部署,大幅降低开发与维护成本🚀

XiaoqiangClub的博客 266

gurobi最新下载安装教程 2023.11

我下载的最新版gurobi支持python3.7-python3.11,这个序号与计算机硬件捆绑,一旦激活就会失效。运行激活码之后,产生的。如果既放置在了上面的默认搜索目录,又设置了。系统环境变量(不是用户环境变量),指向保存的目录和文件名(例如。高版本产生的许可文件兼容低版本。验证不会成功,学术许可不会激活。之后cmd进入命令行,cd进入gurobi所在的。,实测不到一小时即可审核完毕,获得对应的许可。如果学校的网关没有将本校的。系统环境变量指向不同的目录和文件,原厂无关,是学校网络的设置问题。

Cachel Wood的博客 2万+

手把手教你Java文件断点下载

点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!每天14:00更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 Elast...

weixin_44421461的博客 1245

华为OD机考双机位C卷 - 简单的解压缩算法 (Java & Python & JS & GO & C++ & C)

华为OD机考双机位C卷 - 简单的解压缩算法 , 提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。

算法大师! 131

Spring Boot 实现文件断点下载,实战来了!

互联网的连接速度慢且不稳定,有可能由于网络故障导致断开连接。在客户端下载一个大对象时,因网络断开导致上传下载失败的概率就会变得不可忽视。客户端在GET对象请求时通过设置Range头部来告诉接口服务需要从什么位置开始输出对象的数据。判断是否支持断点下载,根据文档:14.35.1 Byte Ranges// 直接判断是否有 Accept-Ranges = bytes直接判断头部HEADHeadObject接口用于获取某个文件(Object)的元信息。使用此接口不会返回文件内容。需知,对应HTTP。

编码行者的博客 928

测绘程序设计——试题一:出租车轨迹数据计算

仅展示试题1的原文,如需了解其余内容,请自行购买图书李老师著作主页-http://ybli.users.sgg.whu.edu.cn/book/

chengzilhc的博客 894

NVIDIA AI 学习与认证指南:从入门到精通

NVIDIA的AI学习与认证体系,凭借其先进的技术背景、丰富的课程资源以及强大的行业认可度,已成为AI学习者和从业者的宝贵资源。通过深入学习NVIDIA的课程和获得认证,学习者可以快速掌握最前沿的AI技术,提升自己的职业竞争力。从基础课程到专业认证,NVIDIA为不同层次的学习者提供了量身定制的学习资源,帮助他们掌握AI的核心技能,提升职业竞争力。是其中的一个亮点,它结合了信息检索与生成式AI的能力,使AI可以从外部知识库中实时提取信息,生成更具深度和准确性的内容。,帮助学习者快速掌握该领域的核心技术。

高校图书馆高级系统架构师/研究馆员,推动高校AI从概念演示到可评审、可交付、可运维:路线图与立项评审、PoC交付、评测回归与上线运维(Baseline/Eval/Ops)。 1881

Http实现断点下载和进度显示

断点下载文件并显示进度

千淘万漉虽辛苦,吹尽狂沙始到金。 697

UCIE Specification详解(五)

Logical Physical Layer(逻辑物理层)

Crazzy_M的博客 1228

Android源码研究Tips

转贴!~ 从去年12月开始写android程序开始,都差不多快一年了。上月google终于公开了android的较完整的源码。最近几天,闲来无事时就给他们提交一些补丁。这里讲一些开发中的技巧,或许对大家有帮助,转载请注明出处:下载源码首先一个问题是http://source.android.com/在国内访问有时,甚至是大多时候,是有问题的。那么

weichaohnu的专栏 3471

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

JDK1.8源码下载及获取、导入IDEA阅读、配置JDK源码

????jdk下载 本文使用JDK版本为jdk1.8 下载地址:https://www.oracle.com/java/technologies/downloads/archive/ ????获取源码 下载jdk压缩包版就可以,解压后,文件路径中会有一个src.zip文件,这个就是jdk源码。 解压后就可以获得jdk源码啦。建议拷贝后换个路径再解压。如下是我存放的路径 ????导入IDEA ☘️新建java项目 使用默认配置,选择下一步 勾选从模板创建项目,再选择下一步 选择jdk源码路径,完成

鳄鱼儿 5643

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

java spring 源码下载_Spring 源码下载

Spring下载下载spring 命令:git clone https://github.com/spring-projects/spring-framework.git下载完成后:Idea打开源码当前源码下载完成后,是无法导入到Eclipse或Idea下的,但是下载包里已经提供相应的操作手段。这里将源码转成Idea打开的工程。在import-into-idea.mdz中,可以看到Pre-comp...

weixin_30396323的博客 462

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

swing-tips-helper: 包含swing900多种小demo快捷助手(内带下载地址)

JAVA-SWING-TIPS github link JAVA-SWING-TIPS:是大牛封装得各种swing小demo, 当你没有思路得时候, 或者想象不到得时候可以参考这个仓库, 大部分代码无依赖纯jdk实现. 少部分依赖java-ws jar包

Record Little 672

前期准备:JDK源码下载

源码下载的方式 通过openjdk官网下载源码 通过HG下载代码库 HG是Mercuial,和Git一样也是一种分布式的版本控制系统。 直接下载代码压缩包 JDK8u download 在线阅读源代码 JDK8u reading code on line 注:后续文章都是基于JDK8U的代码...

技术的学习与积累是个技术活 2049

VS Code开发Java之快速入门

通过将最有可能使用的内容放在完成列表的顶部,可以节省时间。在Visual Studio Code (VS Code)中,利用内置的Java 代码段(Code Snippets)的功能,可以快速的编辑代码。上面的示例是创建一个目录, 然后添加一个.java后缀的文件, VS Code可以自动产生类文件的一些模板,并且main 的入口函数上方会出现运行和调试的链接。在EXPLORER的最下方有一个 Java PRPJECTS的视图,在这个视图中可以很容易的添加Java和类文件以及进行依赖的管理。

oscar999的专栏 1万+

java 监控文件夹变化(钩子文件)

1. 线程轮询扫描  优点:纯java实现,完美跨平台。  缺点:监听文件较多时,需要扫描的量太大;响应不是非常及时,依赖于扫描间隔时间。  2. 文件钩子  优点:事件驱动方式,无目录扫描。  缺点:跟平台相关  Jnotify开发包是个不错的文件钩子库,使用方式如下:  import net.contentobjects.jnotify.JNotify; import n

卖克的专栏 4400

Android 反编译 .vdex、.odex、.dex 文件

Android 反编译 .vdex、.odex、.dex 文件准备环境反编译.odex文件反编译.dex文件反编译.vdex文件Tips 准备环境 1.下载baksmali-2.5.2.jar和smali-2.5.2.jar,baksmali用来反编译odex文件,smali用于将odex文件反编译生成的smali文件,重新打包成dex文件,下载链接: https://bitbucket.org/JesusFreke/smali/downloads/ 2.下载dex2jar-2.0,用于将dex文件编译成j

ldljheropt的博客 6680

走进Java之编译jdk源码编译,手把手教学。

你会看到有一个building.html,这个文件是教你在对应的平台下编译jdk所需要的环境以及如何编译。在VMware中制作linux的系统,比如ubuntu、centos等等,笔者的电脑是Windows。程序员写的一些代码如.java的文件,他们在“工具”的帮助下翻译成了自己能识别的语言.class文件。1、在vm中使用共享文件夹的后果是Windows和linux磁盘的格式是不一样的,导师链接的时候出现问题,在ubuntu20中编译会出现g++版本过高的问题,jdk源码对make4.3兼容性的问题。

小白博客 815

Light Tips项目详解:PHP链表操作从入门到精通

Light Tips是一个专注于算法和PHP编程技巧的开源项目,提供了丰富的数据结构实现,其中链表操作是核心内容之一。本文将带你从基础到进阶,全面掌握PHP链表的实现与应用技巧。 ## 一、什么是链表?PHP实现有何优势? 链表是一种常见的数据结构,由一系列节点组成,每个节点包含数据域和指针域。与数组相比,链表在插入和删除操作上具有O(1)的时间复杂度优势,特别适合频繁修改数据的场景。Ligh

gitblog_00828的博客 240

Android Tips – 填坑手册

出于: androidChina http://www.androidchina.net/3595.html 学习 Android 至今,大大小小的坑没少踩,庆幸的是,在强大的搜索引擎与无私奉献的人们的帮助下,我遇到的坑都顺利地被填平了。 为了便于日后遇到同样的问题时,能免于再次搜索带来的麻烦,我养成了收藏书签的习惯,随着书签(Tips)的日积月累,我想,是时候该有这个项目...

258

linux 勾子 监控文件夹,java 监控文件夹变化(钩子文件)

1. 线程轮询扫描优点:纯java实现,完美跨平台。缺点:监听文件较多时,需要扫描的量太大;响应不是非常及时,依赖于扫描间隔时间。2. 文件钩子优点:事件驱动方式,无目录扫描。缺点:跟平台相关Jnotify开发包是个不错的文件钩子库,使用方式如下:public class FieMonitor {public static void main(String[] args) {String moni...

weixin_28934777的博客 434

zookeeper源码-源码环境搭建-01

文章目录下载源码编译源码编译前奏ant-ivy源码修改 下载源码 我们从 github 上下载 zookeeper 的源码,地址是 https://github.com/apache/zookeeper/archive/release-3.4.12.tar.gz 这里我们选择用 3.4.12 版本的源码作为学习。 编译源码 由于 zk 是 ant 编译环境的,所以这里我们需要先安装 ant 的环境...

皮大虾 494
上一篇: 学习神器:IDEA 源码阅读器!!【送源码】
下一篇: 一款无懈可击的网络管理工具!!【送源码】
架构文摘JGWZ
博客等级 码龄5年 8808粉丝 345原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值