Tips:Java 文件断点下载

【Java技术】基于Http的文件断点续传实现 我对RandomAccessFile类的理解是:RandomAccessFile类是java提供的一个可以用于随机读写文件内容的类,我们可以对RandomAccessFile类关联的文件中的任意位置和任意大小的数据进行任意的读写操作;因此要想完成文件的断点续传操作,该类的使用是必不可少的!(4). 可以通过打开线程任务中模拟意外情况的代码,让下载出现意外,当程序出现意外后,配置文件不会删除,且会记录下所有线程已经完成的下载量,以便于下次执行下载任务的时候,可以在此基础上继续完成下载任务; 阅读详情

前言

❝

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

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

❞

图片

客户端在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);
    }
}
Java常识Tips 1.JVM JVM(Java Virtual Machine),Java虚拟机 JVM是Java平台无关性实现的关键 2.Java程序的执行过程 源文件(.java)-->编译器compiler--->字节码文件(.class)--> 解释器interpreter(JVM解释执行,把字节码解释成具体机器的执行指令)--> 最终平台可执行程序 (一次编译,到处运行) ... 阅读详情

相关推荐

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

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

weixin_45203607的博客 5743

pwm电机调速的原理介绍与代码实现

1、pwm实现调速的原理与介绍 PWM(Pulse Width Modulation)脉冲宽度调制。 1)占空比 pwm占空比就是一个脉冲周期内有效电平在整个周期所占的比例。 通过调节PWM的占空比就能调节IO口上电压的持续性变化,因此也能够控制外设的功率进行持续性变化,也就能控制直流电机的转速快慢。 那么重点就在于如何调节PWM波形的输出。如下图所示 图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4

Clichong 7万+

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

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

weixin_44421461的博客 1245

从mseed到SAC格式转换全攻略:mseed2sac工具安装与批量处理技巧

本文详细介绍了如何将mseed格式的地震数据高效转换为SAC格式,涵盖mseed2sac工具的安装、单文件转换技巧、批量处理自动化实现以及元数据高级处理策略。通过具体命令和脚本示例,帮助地震学研究者快速掌握数据预处理的关键技术,提升波形数据分析效率。

ruby5的博客 929

ThinkBook 16p 2024 BIOS降压定频实战:从解锁CFG Lock到AC Loadline调优

高性能笔记本在满载时频繁撞上温度墙,通常源于固件层默认电压冗余过大,而系统级降压工具又受限于CFG Lock锁定。要根治问题,需要从BIOS固件层面理解电压管理机制——AC/DC Loadline参数控制着CPU在不同负载下的电压请求,通过修改这些负载线值可以安全降低电压,解锁CFG Lock后还能让XTU、ThrottleStop等软件调参工具恢复可用。这种BIOS级调优在工程实践中广泛用于改善散热、稳定频率、压降风扇噪音,尤其适用于联想ThinkBook 16p 2024与拯救者Y9000P等采用HX平

weixin_32496547的博客 391

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

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

oandy0的博客 2782

Qt 5.15.2静态编译避坑实录:MinGW 32位版从源码到Creator配置的全流程踩坑总结

本文详细介绍了Qt 5.15.2 MinGW 32位版本的静态编译全流程,包括环境准备、配置参数优化、编译过程监控及安装后配置。重点解决了静态编译中的常见问题,如参数顺序敏感、路径引号问题等,并提供了性能对比实测数据,帮助开发者高效完成静态编译。

weixin_26749245的博客 271

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

❝互联网的连接速度慢且不稳定,有可能由于网络故障导致断开连接。在客户端下载一个大对象时,因网络断开导致上传下载失败的概率就会变得不可忽视。❞客户端在。

java_121388的博客 780

Python Trimesh库实战:5分钟搞定STL文件解析与3D模型可视化

本文介绍了如何使用Python的Trimesh库快速解析STL文件并进行3D模型可视化。通过简洁的代码示例,演示了从环境搭建、模型加载、几何数据提取到基础变换和批量处理的核心流程,帮助开发者和工程师在5分钟内高效完成3D数据处理与可视化任务。

weixin_32005771的博客 162

《斯图尔特微积分》实战指南:从理论到解题技巧的跨越

本文深入解析《斯图尔特微积分》教材的独特价值与实用学习策略,重点介绍其理论深度与实际应用的完美平衡。通过概念理解、符号语言转换、解题思维框架等五个关键跨越,帮助读者高效掌握微积分核心技巧。文章还提供分层练习、可视化工具等教学实践方法,是提升微积分学习效率的实战指南。

weixin_28432777的博客 398

java断点下载工具,RxDownload

RxDownloadThe download tool based on RxJava . Support multi-threaded download and breakpoint download, intelligent judge whether to support multi-threaded download and breakpoint download.基于RxJava打造的下...

weixin_31542609的博客 535

【即插即用模块】注意力篇 | TGRS 2025 | ASD:自适应频域解耦,动态拆分高低频+空间注意力,频域空间特征双增强!

摘要: FDMF-Net提出了一种频域解耦多模态融合网络,核心组件为振幅谱解耦模块(ASD)。ASD通过自适应频域拆分和频域-空域协同增强,有效分离模态不变与模态特定特征。该模块利用MLP学习动态阈值调整高低频比例,并通过空间注意力分别强化频域特征,在遥感语义分割任务中实现了细节与结构的协同增强。实验表明,ASD模块能减少模态内冗余,提升特征判别性,为多模态数据融合提供了新思路。代码已开源,适用于需要强化细节与结构的视觉任务。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 316

java实现文件下载,批量下载,文件在线预览,word转pdf,excel转pdf

java实现文件下载,批量下载,文件在线预览,word转pdf,excel转pdf

w先生的博客 2160

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

IO流下载文件

IO流的下载,今天项目写的,遇到的问题都会写在下面,如有哪里写的不好,轻喷。: **IO流简介: 流的定义:流是指一连串流动的字符,是以先进先出方式发送信息的通道。 按流向分:输出流:OutputStream和Writer为基类 输入流:InputStream和Reader为基类 按处理数据单元划分:字节流:字节输入流:InputStream基类 ...

p081299的博客 3318

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

探索 Dev-Tips:你的技术开发利器

探索 Dev-Tips:你的技术开发利器 去发现同类优质开源项目:https://gitcode.com/ 项目简介 是一个集成了各类开发者技巧和最佳实践的开源项目,旨在帮助程序员们提升工作效率、解决日常编程中遇到的问题。由GitHub上的著名开发者 coolnameismy 维护,这个资源库涵盖了多种编程语言、工具和技术栈的实用知识。 技术分析 Dev-Tips 使用 Markdown 格式编写...

gitblog_00082的博客 392

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

文件夹、文件目录递归下载:打包成ZIP压缩包

在准备将文件打包成 ZIP 文件之前,需要设置 HTTP 响应的相关信息,包括字符编码、内容类型和文件名称。它首先获取当前文件夹中的文件列表,然后将这些文件添加到ZIP中。获取子文件夹与文件列表需根据自身业务实现,这里基于数据库查询子文件目录,查询文件目录下的文件,同时又涉及了一些处理业务逻辑。单个文件目录打包ZIP下载与文件目录递归打包ZIP下载类似,首先来看看单个文件目录中的文件是如何打包ZIP下载的。递归文件目录打包ZIP下载相比单个文件目录打包ZIP下载,无非是多了个递归文件目录的操作。

2401_87705318的博客 705

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

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

Record Little 672

Top 10 Java Debugging Tips with Eclipse(Eclipse调试Java的10个技巧)

在本教程中,我们将看到使用Eclipse调试Java应用程序。调试可以帮助我们识别和解决应用程序中的缺陷。我们将重点放在运行时间的问题,而不是编译时错误。有提供像gdb的命令行调试器。在本教程中,我们将集中在基于GUI的调试,我们把我们最喜爱的IDE Eclipse来运行,通过本教程。虽然我们说的Eclipse,点大多是通用的,适用于调试使用的IDE像NetBeans。

9421

Java文件下载中文名无法显示&乱码

最近做了一个文件下载的需求,但是下载的文件名称如果是中文名,下载后出现名称无法显示的问题。查看资料后最终解决了。 原因:   因为用post方式提交的,所以用Servlet做的,设置的头信息里面需要对文件名称做处理,Header中只支持ASCII,传输的文件名必须是ASCII(为什么只支持ASCII)否则当出现中文名文件时,就出现异常。 Tips: 只是针对header!!! 代...

yinghuacao_dong的博客 8012

Java基础2-工具篇:Eclipse下载安装及基本使用

工欲善其事必先利其器,学习Java,我们需要IDE编程工具,这里选取的是Eclipse。 实践时间:2020年2月18日 一、工具安装 下载地址:(推荐使用下载包解压的方式使用Eclipse) https://www.eclipse.org/downloads/packages/ 1.进入之后,我们要下载的Eclipse IDE 为Java开发准备的版本,然后在右边找到自己对应的系统和根...

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值