通过url下载网络文件至本地

所需依赖和工具类代码
所需依赖

        <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.5</version></dependency>        <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>

工具类代码

package com.example.util;import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 下载网络文件至本地** @Author: haoyalei* @CreateTime: 2021-06-04 10:10* @Description: HttpDownload*/
public class HttpDownloadUtil {public static final int cache = 10 * 1024;public static void main(String[] args) {String url = "http://localhost:8080/file/1657781484678.mp3";String targetUrl = "../newDir/";HttpDownloadUtil.download(url,targetUrl);}/*** 根据url下载文件,保存到filepath中** @param url 文件的url* @param diskUrl 本地存储路径* @return*/public static String download(String url, String diskUrl) {String filepath = "";String filename = "";try {HttpClient client = HttpClients.createDefault();HttpGet httpget = new HttpGet(url);// 加入Referer,防止防盗链httpget.setHeader("Referer", url);HttpResponse response = client.execute(httpget);HttpEntity entity = response.getEntity();InputStream is = entity.getContent();if (StringUtils.isBlank(filepath)){Map<String,String> map = getFilePath(response,url,diskUrl);filepath = map.get("filepath");filename = map.get("filename");}File file = new File(filepath);file.getParentFile().mkdirs();FileOutputStream fileout = new FileOutputStream(file);byte[] buffer = new byte[cache];int ch = 0;while ((ch = is.read(buffer)) != -1) {fileout.write(buffer, 0, ch);}is.close();fileout.flush();fileout.close();} catch (Exception e) {e.printStackTrace();}return filename;}/*** 根据contentType 获取对应的后缀 (列出常用的ContentType对应的后缀)** @param contentType* @return*/static String getContentType(String contentType){HashMap<String, String> map = new HashMap<String, String>() {{put("application/msword", ".doc");put("image/jpeg", ".jpeg");put("application/x-jpg", ".jpg");put("video/mpeg4", ".mp4");put("application/pdf", ".pdf");put("application/x-png", ".png");put("application/x-ppt", ".ppt");put("application/postscript", ".ps");put("application/vnd.android.package-archive", ".apk");put("video/avi", ".avi");put("text/html", ".htm");put("image/png", ".png");put("application/x-png", ".png");put("audio/mpeg", ".mp3");put("image/gif", ".gif");}};return map.get(contentType);}/*** 获取response要下载的文件的默认路径** @param response* @return*/public static Map<String,String> getFilePath(HttpResponse response, String url, String diskUrl) {Map<String,String> map = new HashMap<>();String filepath = diskUrl;String filename = getFileName(response, url);String contentType = response.getEntity().getContentType().getValue();if(StringUtils.isNotEmpty(contentType)){// 获取后缀String suffix = getContentType(contentType);String regEx = ".+(.+)$";Pattern p = Pattern.compile(regEx);Matcher m = p.matcher(filename);if (!m.find()) {// 如果正则匹配后没有后缀,则需要通过response中的ContentType的值进行匹配if(StringUtils.isNoneBlank(suffix)){filename = filename + suffix;}}else{if(filename.length()>20){filename = getRandomFileName() + suffix;}}}if (filename != null) {filepath += filename;} else {filepath += getRandomFileName();}map.put("filename", filename);map.put("filepath", filepath);return map;}/*** 获取response header中Content-Disposition中的filename值* @param response* @param url* @return*/public static String getFileName(HttpResponse response,String url) {Header contentHeader = response.getFirstHeader("Content-Disposition");String filename = null;if (contentHeader != null) {// 如果contentHeader存在HeaderElement[] values = contentHeader.getElements();if (values.length == 1) {NameValuePair param = values[0].getParameterByName("filename");if (param != null) {try {filename = param.getValue();} catch (Exception e) {e.printStackTrace();}}}}else{// 正则匹配后缀filename = getSuffix(url);}return filename;}/*** 获取随机文件名** @return*/public static String getRandomFileName() {return String.valueOf(System.currentTimeMillis());}/*** 获取文件名后缀* @param url* @return*/public static String getSuffix(String url) {// 正则表达式“.+/(.+)$”的含义就是:被匹配的字符串以任意字符序列开始,后边紧跟着字符“/”,// 最后以任意字符序列结尾,“()”代表分组操作,这里就是把文件名做为分组,匹配完毕我们就可以通过Matcher// 类的group方法取到我们所定义的分组了。需要注意的这里的分组的索引值是从1开始的,所以取第一个分组的方法是m.group(1)而不是m.group(0)。String regEx = ".+/(.+)$";Pattern p = Pattern.compile(regEx);Matcher m = p.matcher(url);if (!m.find()) {// 格式错误,则随机生成个文件名return String.valueOf(System.currentTimeMillis());}return m.group(1);}
}

运行main方法结果:


屏蔽org.apache.http的日志
另外有一个小问题,在运行main方法的时候,控制台会打印很多org.apache.http的日志


实际上,这写日志并没有什么作用,我们可以在main方法中添加以下代码来屏蔽这些日志信息

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;public static void main(String[] args) {Logger logger = (Logger) LoggerFactory.getLogger("org.apache.http");logger.setLevel(Level.INFO);logger.setAdditive(false);String url = "http://10.220.10.19:9180/file/c26055d232d5426ba75dca34c9b56230.mp3";String targetUrl = "../newDir/";HttpDownloadUtil.download(url,targetUrl);}

如此一来控制台就会清爽很多,也容易debug

手动添加Content-Type
比如有些Content-Type并没有在此工具类的getContentType(String contentType)方法中收录,这可能会导致有些文件下载下来没有文件后缀,如下图:


这时候就需要我们手动添加网络文件的后缀:
我们需要在getFilePath(HttpResponse response, String url, String diskUrl)方法中先打印此文件的Content-Type,然后在getContentType(String contentType)方法的map中添加对应的键值对

但是由于之前的日志打印太多了,运行结果中根本找不到打印在控制台的Content-Type信息

 这时候关闭这些无效的日志就显得很重要了,让我们在main方法中添加设置日志等级的代码之后,再次运行main方法查看结果:

这时候我们便知道mp3对应的Content-Type是audio/mpeg,随后便在getContentType(String contentType)添加键值对即可

再次运行main方法,查看文件是否有后缀:

成功!
————————————————
版权声明:本文为CSDN博主「Hyalei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45379185/article/details/125844724

【转】java下载网络文件至本地相关推荐

  1. java下载网络文件至本地

    通过url下载网络文件至本地 所需依赖和工具类代码 所需依赖 <dependency><groupId>org.apache.httpcomponents</groupI ...

  2. java下载网络中的文件,java下载网络文件解决思路

    java下载网络文件 下面这段代码是下载一个http网络文件的代码,但有时候下载下来的图片是完整的,有时候下载下来的不完整,还有下载的ppt,pdf之类,也是打不开的.请大件们给指导一下,小弟感激不尽 ...

  3. R语言使用download.file函数下载网络文件到本地(Download File from the Internet)

    R语言使用download.file函数下载网络文件到本地(Download File from the Internet) 目录 R语言使用download.file函数下载网络文件到本地(Down ...

  4. python urlretrieve_使用urllib库的urlretrieve()方法下载网络文件到本地的方法

    概述 见源码 源码 # !/usr/bin/env python # -*- coding:utf-8 -*- """ 图片(文件)下载,核心方法是 urllib.url ...

  5. java下载网络文件_java下载网络文件的方法有哪些

    下载网络文件的方法有:字节流下载 apache的FileUtils工具包下载 NIO下载 实现代码如下:package com.dsp.rpc.metricelf; import org.apache ...

  6. java下载网络文件的N种方式

    通过java api下载网络文件的方法有很多,在这里我做个汇总,主要方式有以下几种: 1.使用 common-io库下载文件,需要引入commons-io-2.6.jar public static ...

  7. springboot项目下载网络文件到本地,返回网络路径,简单实用

    刚开始用这种方式 public static String downloadImage(String fileUrl ) {long l = 0L;String path = null;String ...

  8. java下载远程文件到本地

    /**       * 下载远程文件并保存到本地        * @param remoteFilePath 远程文件路径        * @param localFilePath 本地文件路径  ...

  9. Java实现下载网络文件至本地

    文章目录 背景介绍 实现方案 参考资料 背景介绍 来了一个新需求,要求我把别人的网站图片给下载下来,我当时心想,鼠标右键另存为本地不就行了吗?然后给我了一个网站,光数据就是几十页,图片不计其数. 实现 ...

最新文章

  1. R之ddlpy函数学习[转载]
  2. Ubuntu系统备份工具大全(官方整理推荐)
  3. 【HDU - 5968】异或密码(思维,STLmap)
  4. android下挂串口中断,请大神看看为啥串口中断无法打断定时器中断
  5. 旋转成分矩阵结果分析_30分钟学会PCA主成分分析
  6. Linux下Apache与Tomcat的完全分布式集群配置(负载均衡)
  7. linux定时备份前一天,linux定时备份
  8. postgresql 自定义表变量_Oracle GoldenGate新支持开源关系型数据库PostgreSQL
  9. oracle查看数据库文件大小
  10. matlab仿真光学拍,MATLAB光学干涉实验的仿真研究
  11. swing html 字体颜色,swing sister
  12. 弹性伸缩Auto Scaling
  13. RTX 4070TI和RTX 4090性能差距 RTX4070ti和4070区别对比
  14. NTFS下的USN日志文件
  15. lms语音降噪matlab实现_ANC主动降噪理论及Matlab代码实现
  16. (要更新)SRAM、DRAM、SDRAM、DDR异同
  17. ULua Simpleframework环境安装详解
  18. 大屏自适应等展示问题
  19. 重大喜讯!精灵云校V5.0家校互通正式上线,助力机构打造完美服务体系!
  20. 七、网络安全之AAA认证技术详解

热门文章

  1. 画册设计的方法有哪些?新手怎么设计好画册?
  2. 高清动漫视频-动漫专题-好看动画电影-新动漫岛网站制作历程
  3. 【入门向】光流法(optical flow)基本原理+深度学习中的应用【FlowNet】【RAFT】
  4. 华为OD机试题 - Excel 单元格数值统计(JavaScript)| 机考必刷
  5. Aurora的自动驾驶技术介绍
  6. 5个免费抠图工具,PS直接下岗
  7. 优秀的测试开发应该具备的六大能力
  8. HDFS 压缩算法对比
  9. Xcode使用介绍之一:Xcode简介+创建App应用
  10. flutter全屏时钟!9次Android面试经验总结,学习路线+知识点梳理