java下载网络文件至本地
通过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下载网络文件至本地相关推荐
- 【转】java下载网络文件至本地
通过url下载网络文件至本地 所需依赖和工具类代码 所需依赖 <dependency><groupId>org.apache.httpcomponents</groupI ...
- java下载网络中的文件,java下载网络文件解决思路
java下载网络文件 下面这段代码是下载一个http网络文件的代码,但有时候下载下来的图片是完整的,有时候下载下来的不完整,还有下载的ppt,pdf之类,也是打不开的.请大件们给指导一下,小弟感激不尽 ...
- R语言使用download.file函数下载网络文件到本地(Download File from the Internet)
R语言使用download.file函数下载网络文件到本地(Download File from the Internet) 目录 R语言使用download.file函数下载网络文件到本地(Down ...
- python urlretrieve_使用urllib库的urlretrieve()方法下载网络文件到本地的方法
概述 见源码 源码 # !/usr/bin/env python # -*- coding:utf-8 -*- """ 图片(文件)下载,核心方法是 urllib.url ...
- java下载网络文件_java下载网络文件的方法有哪些
下载网络文件的方法有:字节流下载 apache的FileUtils工具包下载 NIO下载 实现代码如下:package com.dsp.rpc.metricelf; import org.apache ...
- java下载网络文件的N种方式
通过java api下载网络文件的方法有很多,在这里我做个汇总,主要方式有以下几种: 1.使用 common-io库下载文件,需要引入commons-io-2.6.jar public static ...
- springboot项目下载网络文件到本地,返回网络路径,简单实用
刚开始用这种方式 public static String downloadImage(String fileUrl ) {long l = 0L;String path = null;String ...
- java下载远程文件到本地
/** * 下载远程文件并保存到本地 * @param remoteFilePath 远程文件路径 * @param localFilePath 本地文件路径 ...
- Java实现下载网络文件至本地
文章目录 背景介绍 实现方案 参考资料 背景介绍 来了一个新需求,要求我把别人的网站图片给下载下来,我当时心想,鼠标右键另存为本地不就行了吗?然后给我了一个网站,光数据就是几十页,图片不计其数. 实现 ...
最新文章
- mysqldump定时备份数据库
- SENetSKNet 解读
- 《Go 语言编程之旅》送煎架和站长写的书
- 【MFC系列2】Win32项目转换为MFC项目
- 修改文章更新缓存php,php – 使用liipImagineBundle更新/删除记录时删除/更新缓存的图像...
- Hibernate中的sql的所有的查询
- matlab 获取axes图片,matlabaxes显示图片
- 平安证券最新股票池强荐4只股
- 从头搭建DVWA平台
- 狄利克雷卷积_算法学习笔记(35): 狄利克雷卷积
- mysql语句distinct_MySQL DISTINCT语句
- Type mismatch affecting row number 0 and column type 'BIGINT': Value [7] is of type [Integer] and c
- java 雷达图_Java 创建Excel雷达图
- 考研数据结构学习与总结笔记---1.1数据结构的基本概念
- 认定高新技术企业能得到什么好处
- 创业如何解决资金不足的问题
- 掌握JavaScript
- 私有化部署|短视频|带直播|即时通讯|IM|聊天app|支持二开丨视频会议丨支付红包
- windows系统封装
- 山石网科Hillstone防火墙VLAN接口配置方案(官新版)