通过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方法,查看文件是否有后缀:

成功!

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. mysqldump定时备份数据库
  2. SENetSKNet 解读
  3. 《Go 语言编程之旅》送煎架和站长写的书
  4. 【MFC系列2】Win32项目转换为MFC项目
  5. 修改文章更新缓存php,php – 使用liipImagineBundle更新/删除记录时删除/更新缓存的图像...
  6. Hibernate中的sql的所有的查询
  7. matlab 获取axes图片,matlabaxes显示图片
  8. 平安证券最新股票池强荐4只股
  9. 从头搭建DVWA平台
  10. 狄利克雷卷积_算法学习笔记(35): 狄利克雷卷积
  11. mysql语句distinct_MySQL DISTINCT语句
  12. Type mismatch affecting row number 0 and column type 'BIGINT': Value [7] is of type [Integer] and c
  13. java 雷达图_Java 创建Excel雷达图
  14. 考研数据结构学习与总结笔记---1.1数据结构的基本概念
  15. 认定高新技术企业能得到什么好处
  16. 创业如何解决资金不足的问题
  17. 掌握JavaScript
  18. 私有化部署|短视频|带直播|即时通讯|IM|聊天app|支持二开丨视频会议丨支付红包
  19. windows系统封装
  20. 山石网科Hillstone防火墙VLAN接口配置方案(官新版)

热门文章

  1. 如何使用IOS自动化测试工具UIAutomation
  2. js-多个果冻按钮之当前果冻按钮弹性特效
  3. 关于启发式算法、元启发式算法以及超启发式算法的理解
  4. 关于NS-2仿真中移动节点的设置
  5. COleDateTime ParseDateTime 方法
  6. 5.2 Lasso回归分析
  7. TM4C1294使用
  8. 如何用 R 绘制交互式社会网络图?
  9. ubuntu18.04安装CUDA
  10. 如何在Linux下安装chrome浏览器