在Java服务中有复杂网络环境下下载大文件的需求,一开始自己写了一个多线程下载,但遇到校园网下载1G以上大文件时直接卡死了。
经调研后决定用aria下载器,成熟稳定,避免自己去处理各种网络问题。下面记录一下windows和ubuntu系统上分别使用aria进行文件下载的步骤。

标题aria下载安装,打开jsonrpc

# ubuntu系统
sudo apt install -y aria2
aria2c --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all -c -D# windows系统
# 1. 下载aria2-1.36.0-win-64bit-build1.zip,https://github.com/aria2/aria2/releases
# 2. 解压文件
# 3. 执行命令:
aria2c --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all -c -D

保持aria在线的办法

写了一个监控脚本如下,放入crontab定时任务

log "aria heartbeat start"
result=$(curl -X GET --header 'Accept: application/json' 'http://localhost:6800/jsonrpc' | jq '.jsonrpc')
if [ "$result" == "" ]
thenlog "aria heartbeat failed"aria2c --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all -c -D
fi

Java 代码调用 jsonrpc

/*** jsonrpc 方式调用 Aria 下载器*/
@Slf4j
@Component
public class AriaClient {@Value("${aria.url}")private String uri;private String token = "";@Autowiredprivate RestTemplate restTemplate;/*** url下载把文件保存到本地** @param url* @param dir      下载文件保存到的文件夹* @param filename 下载文件名* @return* @throws SportException*/public String addByUrl(String url, String dir, String filename) throws SportException {AriaRequest request = AriaRequestFactory.getAddUriRequest(token, url, dir, filename);String resultJson = post(request);JSONObject JSONObject = JSON.parseObject(resultJson);String gid = JSONObject.getString("result");log.info("addByUrl, url={}, dir={}, filename={}, gid={}", url, dir, filename, gid);return gid;}/*** url下载把文件保存到本地** @param url* @param fullPath 本地文件完整路径* @return* @throws SportException*/public String addByUrl(String url, String fullPath) throws SportException {return addByUrl(url, FileUtils.getDirFromPath(fullPath), FileUtils.getFileNameFromPath(fullPath));}/*** 移除一个下载项(正在下载的任务或者已经下载完成的结果)** @param id*/public boolean remove(String id) {AriaDownloadTask ariaDownloadTask = get(id);if (ariaDownloadTask.getStatus() == AriaDownloadStatus.active) {AriaRequest removeRequest = AriaRequestFactory.getRemoveRequest(token, id);return execute(removeRequest);} else {AriaRequest removeResultRequest = AriaRequestFactory.getRemoveResultRequest(token, id);return execute(removeResultRequest);}}/*** 移除所有下载项*/public void remove() {List<AriaDownloadTask> ariaDownloadTasks = get();for (AriaDownloadTask ariaDownloadTask : ariaDownloadTasks) {remove(ariaDownloadTask.getGid());}}/*** 开始/继续下载一个任务** @param id* @return*/public boolean start(String id) {AriaRequest pauseRequest = AriaRequestFactory.getUnpauseRequest(token, id);return execute(pauseRequest);}/*** 开始所有任务** @return*/public boolean start() {AriaRequest pauseRequest = AriaRequestFactory.getUnpauseAllRequest(token);return execute(pauseRequest);}/*** 暂停一个任务* <p>* 只能暂停正在下载的任务,否则会抛出异常** @param id* @return*/public boolean stop(String id) {AriaRequest pauseRequest = AriaRequestFactory.getPauseRequest(token, id);return execute(pauseRequest);}/*** 暂停所有任务** @return*/public boolean stop() {AriaRequest pauseRequest = AriaRequestFactory.getPauseAllRequest(token);return execute(pauseRequest);}/*** 获取一个下载任务** @param gid* @return*/public AriaDownloadTask get(String gid) {AriaRequest tellStatusRequest = AriaRequestFactory.getTellStatusRequest(token, gid);String resultJson = post(tellStatusRequest);JSONObject resultObject = JSON.parseObject(resultJson);return JSON.parseObject(resultObject.getString("result"), AriaDownloadTask.class);}/*** 获取所有下载任务,包括正在下载的、在等待的、已经停止的** @return*/public List<AriaDownloadTask> get() {AriaRequest tellActiveRequest = AriaRequestFactory.getTellActiveRequest(token);String activeResultJson = post(tellActiveRequest);List<AriaDownloadTask> tasks = getTasksFromJson(activeResultJson);AriaRequest tellWaitingRequest = AriaRequestFactory.getTellWaitingRequest(token);String waitingResultJson = post(tellWaitingRequest);tasks.addAll(getTasksFromJson(waitingResultJson));AriaRequest tellStoppedRequest = AriaRequestFactory.getTellStoppedRequest(token);String stoppedRequestJson = post(tellStoppedRequest);tasks.addAll(getTasksFromJson(stoppedRequestJson));return tasks;}private String post(AriaRequest request) throws SportException {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(request));jsonObject.put("params", request.getParams());HttpEntity entity = new HttpEntity(jsonObject.toJSONString(), headers);try { ResponseEntity<String> temp = restTemplate.postForEntity(uri, entity, String.class);String response = temp.getBody();if (temp.getStatusCodeValue() == SC_OK) return response;else {AriaErrorResponse ariaErrorResponse = JSON.parseObject(response, AriaErrorResponse.class);throw new SportException(ARIA_REQUEST_ERROR, ariaErrorResponse.getMessage());}} catch (HttpClientErrorException e) {if (e.getRawStatusCode() == SC_BAD_REQUEST || e.getRawStatusCode() == SC_INTERNAL_SERVER_ERROR) {throw new SportException(ARIA_REQUEST_ERROR, e.getMessage());} else {throw new SportException(ARIA_UNKNOWN_ERROR, e.getMessage());}} catch (RestClientException e) {throw new SportException(ARIA_NOT_AVAILABLE, e.getMessage());}}private boolean execute(AriaRequest pauseRequest) {try {post(pauseRequest);return true;} catch (SportException e) {log.error(e.getMessage());return false;}}private List<AriaDownloadTask> getTasksFromJson(String tellJson) {List<AriaDownloadTask> ret = new LinkedList<>();JSONObject JSONObject = JSON.parseObject(tellJson);JSONArray jsonArray = JSONObject.getJSONArray("result");jsonArray.forEach(element -> ret.add(JSON.parseObject(element.toString(), AriaDownloadTask.class)));return ret;}}

文件下载中遇到的一些需要注意的地方

1. ubuntu 系统上 aria 会在未完成下载时就创建文件。

具体场景:例如指定url下载到一个1G的文件到 /home/user/test.zip。在任务创建后,/home/user/test.zip 就会被创建,且文件大小=1G。md5sum /home/user/test.zip 不等于正确值,且随着下载一直在变化。在某些情况下,这会造成干扰,让人或系统误以为文件已经下载完成,开始后续的操作,出现错误。

我的解决方案:给aria的指令改成创建 /home/user/test.zip.temp 甚至 /home/user/test.zip.uuid,完成后再把 /home/user/test.zip.temp 或 /home/user/test.zip.uuid 移动到 /home/user/test.zip

2. 重复下载

具体场景:给 aria 发送多次相同的 url 和 filename的下载指令,它会重复下载。

我的解决方案:把正在下载的文件放入一个map,下载前验证一下。

其他解决方案:下载前读取所有aria任务,判断是否重复。

3. url失效aria会一直在下载中

我的解决方案:下载前判断url返回的httpcode,必须是2xx;下载中间记录上一次下载下载进度,长时间不动则关闭该任务。

Java使用Aria2c进行文件下载相关推荐

  1. java 防止文件下载_Spring,Java:流式文件下载以避免内存不足错误

    我正在开发一个Spring MVC应用程序,用户可以在其中下载文件.用户可以点击触发下载机制的附件.Spring,Java:流式文件下载以避免内存不足错误 昨天,当该多个下载和两个具有约2 GB的文件 ...

  2. JAVA中的通用文件下载接口

    本文记录下JAVA中的通用文件下载接口,每次都上网找,挺麻烦的. 文章目录 概述 概述 /*** 通用下载请求** @param filePathName 文件路径*/@GetMapping(&quo ...

  3. Java后台Controller实现文件下载操作

    代码 参数: 1.filePath:文件的绝对路径(d:\download\a.xlsx) 2.fileName(a.xlsx) 3.编码格式(GBK) 4.response.request不介绍了, ...

  4. java后台实现excel文件下载功能

    java后台实现excel文件下载功能  java中对于excel文件的操作,有读取,写入,上传等功能,在对excel文件进行操作时,为了让使用者更加直观的制作excel数据,必然会有下载模板exce ...

  5. Java Web学习总结-文件下载

    参考资料:https://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件 ...

  6. java下文_java实现文件下载的两种方式

    本文实例为大家分享了java实现文件下载的具体代码,供大家参考,具体内容如下 public HttpServletResponse download(String path, HttpServletR ...

  7. java实现简单的文件下载

    文件下载 需要在WebRoot 下创建images文件夹 并且放入test.txt文件 创建jsp文件夹 放入01.jsp index.jsp 不变 web.xml需要配置servlet 适合初学者研 ...

  8. java下载pdf_java实现文件下载..pdf

    java实现文件下载. 在 BlogJava上已经有一位作者阐述了文件上传的问题, 地址是在 Struts 2中实现文件上传 , 因此我就不再讨论那个话题了.我今天简单介绍一下 Struts 2的文件 ...

  9. java 下载限速_Java 文件下载限流算法

    在做文件下载功能时,为了避免下载功能将服务器的带宽打满,从而影响服务器的其他服务.我们可以设计一个限流器来限制下载的速率,从而限制下载服务所占用的带宽. 一.算法思路 定义一个数据块chunk(单位 ...

最新文章

  1. 通过页面埋点做监控却不影响性能?解密ARMS前端监控数据上报技术内幕
  2. 程序员没有天才:暴风影音首席架构师鲍金龙访谈
  3. 2021年春季学期-信号与系统-第十五次作业参考答案
  4. 【数据挖掘知识点六】假设检验
  5. UA PHYS515A 电磁理论IV 时变电磁场理论6 用含时Green函数求解时变电磁场问题的例子
  6. bzoj 1901: Zju2112 Dynamic Rankings
  7. cute editor详细设置
  8. 请说说你对标签语义化的理解?
  9. BLOB,TEXT GEOMETRY or JSON column 'xxx' can't have a default value query问题解决
  10. 10-05 Java 内部类概述和讲解
  11. 递归法:实现指数型枚举(二叉树递归)
  12. 转:从框架看PHP的五种境界及各自的薪资待遇(仅限于二三线城市,一线除外)...
  13. 移植opencv2.4.9到android过程记录
  14. 蓝桥杯、PAT、CCF CSP、团体程序设计天梯赛、传智杯、全国高校计算机能力挑战赛、软考等大学生编程比赛/考试介绍
  15. ES6语法及vue复习
  16. 使用@Slf4j的正确方法
  17. 通过调试微信小程序示例代码解析flex布局参数功能(一)
  18. bigdicmal除法精度设置_使用java求高精度除法,要求保留N位小数
  19. Python break用法详解
  20. [附源码]java毕业设计社区健康服务平台管理系统lunwen

热门文章

  1. 应该如何选择IT培训机构
  2. SuperMap iClient3D for WebGL教程(影像篇)-SingleTileImageryProvider
  3. ftp软件是什么如何使用,ftp软件是什么如何使用
  4. python爬取小说并下载_python爬取138看书网小说源码
  5. oracle将数据导出到CSV文件-ok
  6. 【读点论文】AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE(ViT)像处理自然语言那样处理图片
  7. 飞机电子式模拟空速表的设计与制作
  8. 求PCB 自动开料软件源代码
  9. 基于labview的AM调制以及解调
  10. Android蓝牙bt/ble开发