JAVA 文件上传下载工具类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
* 文件操作工具类
* @date 2020/8/4 - 14:20
*/
@Slf4j
public class FileUtil extends FileUtils{
/**
* 读取服务器相对路径下的文件并下载
* @param request 请求
* @param response 响应
* @param srcPath 源文件路径
* @param targetName 响应文件名称
* @param delSrcFile 是否删除源文件
* @since 2020/8/4 14:00
* @author liudongxin
*/
public static void downloadFile(HttpServletRequest request, HttpServletResponse response, String srcPath, String targetName,boolean delSrcFile) {
try {
// 读取源文件
File file = readLocalFile(uploadPath + srcPath);
if(StringUtils.isNotNull(file)){
//文件不存在
if (!file.exists() || file.isDirectory()) {
log.error("要下载的文件不存在!");
throw new CustomException("对不起!您要下载的文件不存在!");
}
//设置响应类型并下载
download(request,response,file,targetName);
//删除源文件
if(delSrcFile){
if(!file.delete()){
throw new CustomException("下载文件,删除源文件失败!");
}
}
}else {
log.error("资源不存在或路径不正确");
throw new CustomException("对不起!您要下载的资源不存在!");
}
} catch (Exception ex) {
log.error(CustomException.getExceptionDetail(ex));
throw new CustomException("下载资源出错了!");
}
}
/**
* 读取本工程类路径下的文件并下载
* @param request 请求
* @param response 响应
* @param srcPath 源文件路径
* @param targetName 响应文件名称
* @param delSrcFile 是否删除源文件
* @since 2020/8/4 14:00
*/
public static void downloadResFile(HttpServletRequest request, HttpServletResponse response, String srcPath, String targetName, boolean delSrcFile) {
try {
// 读取源文件
ClassPathResource classPathResource = readLocalResFile(srcPath);
if(StringUtils.isNotNull(classPathResource)){
//文件不存在
if (!classPathResource.getFile().exists() || classPathResource.getFile().isDirectory()) {
log.error("要下载的文件不存在!");
throw new CustomException("对不起!您要下载的文件不存在!");
}
//设置响应类型并下载
download(request,response,classPathResource.getFile(),targetName);
//删除源文件
if(delSrcFile){
if(!classPathResource.getFile().delete()){
throw new CustomException("下载文件,删除源文件失败!");
}
}
}else {
log.error("资源不存在或路径不正确");
throw new CustomException("对不起!您要下载的资源不存在!");
}
} catch (Exception ex) {
log.error(CustomException.getExceptionDetail(ex));
throw new CustomException("下载资源出错了!");
}
}
/**
* @param request 请求
* @param response 响应
* @param file 要下载的文件
* @param targetName 响应文件名称
*/
private static void download(HttpServletRequest request, HttpServletResponse response, File file, String targetName) {
//输入流
FileInputStream in = null;
//输出流
OutputStream out = null;
try {
//读取文件
in = new FileInputStream(file);
//设置响应类型
String strContentType = getFileContentType(getExt(targetName));
response.reset();//重置响应
response.setContentType(strContentType);
//获得输出流
out = response.getOutputStream();
//设置编码格式
if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
targetName = URLEncoder.encode(targetName, StandardCharsets.UTF_8.displayName());
} else {
targetName = new String(targetName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
}
//设置响应头
response.setHeader("Content-Disposition", "attachment;filename="+targetName);
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", 0);
//设置显示响应文件大小
response.setContentLength(in.available());
byte[] buf = new byte[1024];
int len;
while((len = in.read(buf)) != -1){
//输出响应
out.write(buf, 0, len);
}
}catch (Exception e){
log.error(CustomException.getExceptionDetail(e));
throw new CustomException("下载资源出错了!");
}finally {
try {
if(out != null){
out.flush();
out.close();
}
if(in != null){
in.close();
}
} catch (IOException e) {
log.error(CustomException.getExceptionDetail(e));
}
}
}
/**
* 读取服务器相对路径下的文件
* @since 2020/8/4 14:30
*/
public static File readLocalFile(String resourcePath) {
File file = new File(resourcePath);
//文件存在
if(file.exists()) {
return file;
}else {
if(file.isDirectory()){
//不存在创建文件夹
if(!file.mkdirs()){
throw new CustomException(resourcePath + " 文件夹不存在,主动创建失败!");
}
return file;
}
return null;
}
}
/**
* 读取本工程内类路径下的文件
* @since 2020/8/4 14:30
*/
public static ClassPathResource readLocalResFile(String resourcePath) {
ClassPathResource classPathResource = new ClassPathResource(resourcePath);
//文件存在
if(classPathResource.exists()) {
return classPathResource;
}
return null;
}
/**
* 单文件上传,指定路径 0文件为空 1成功 2异常
* @since 2020/8/4 14:50
*/
public static int saveSingleFile(File file,String targetDirectory) {
try {
//判断文件夹是否存在,不存在则创建
File filePath = checkAndCreateFile(targetDirectory);
if (file != null) {
String realName = UUID.randomUUID().toString()+ getExt(file.getName());
File target = new File(filePath, realName);
FileUtils.copyFile(file, target);
return 1;
}
return 0;
} catch (Exception e) {
log.error(e.getMessage());
}
return 2;
}
/**
* 单文件上传 0文件为空 1成功 2异常
* @since 2020/8/4 14:53
*/
public static int saveSingleFile(File file) {
try {
//判断文件夹是否存在,不存在则创建
File filePath = checkAndCreateFile();
if (file != null) {
String realName = UUID.randomUUID().toString() + getExt(file.getName());
File target = new File(filePath, realName);
FileUtils.copyFile(file, target);
return 1;
}
return 0;
} catch (Exception e) {
log.error(e.getMessage());
}
return 2;
}
/**
* 单文件上传 0文件为空 1成功 2异常
* @since 2020/8/4 15:00
*/
public static File saveFile(File file) {
try {
//判断文件夹是否存在,不存在则创建
File filePath = checkAndCreateFile();
String realName = UUID.randomUUID().toString() + getExt(file.getName());
File target = new File(filePath, realName);
FileUtils.copyFile(file, target);
return target;
} catch (Exception e) {
log.error(e.getMessage());
}
return null;
}
/**
* 多文件上传,指定路径 0文件为空 1成功 2异常
* @since 2020/8/4 15:05
*/
public static int saveFile(List<File> files,String targetDirectory) {
try {
//判断文件夹是否存在,不存在则创建
File filePath = checkAndCreateFile(targetDirectory);
if (files != null) {
for (File file : files) {
String realName = UUID.randomUUID().toString() + getExt(file.getName());
File target = new File(filePath, realName);
FileUtils.copyFile(file, target);
}
return 1;
}
return 0;
} catch (Exception e) {
log.error(e.getMessage());
}
return 2;
}
/**
* 多文件上传 0文件为空 1成功 2异常
* @since 2020/8/4 15:11
*/
public static int saveFile(List<File> files) {
try {
//判断文件夹是否存在,不存在则创建
File filePath = checkAndCreateFile();
if (files != null) {
for (File file : files) {
String realName = UUID.randomUUID().toString() + getExt(file.getName());
File target = new File(filePath.getPath(), realName);
FileUtils.copyFile(file, target);
}
return 1;
}
return 0;
} catch (Exception e) {
log.error(e.getMessage());
}
return 2;
}
/**
* MultipartFile 转 File并存储到指定路径
* @param multipartFile 需要转换的文件
* @param targetPath 转换过后的文件存放的路径
* @since 2020/9/4 15:14
*/
public static File multipartFileToFile(MultipartFile multipartFile,String targetPath) throws Exception {
File newFile = new File(targetPath);
//开始转换
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), newFile);
return newFile;
}
/**
* MultipartFile 转 File并存储到默认路径
* @author liudongxin
* @since 2020/8/4 15:54
*/
public static File multipartFileToFile(MultipartFile file) throws Exception {
//判断文件夹是否存在,不存在则创建
File filePath = checkAndCreateFile();
//转换后的文件
File toFile = null;
//文件不为空,进行转换
if(null != file && file.getSize() > 0){
InputStream ins = file.getInputStream();
toFile = new File(filePath, Objects.requireNonNull(file.getOriginalFilename()));
toFile = inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
}
/**
* MultipartFile 转 File,具体转换方法
* @since 2020/8/4 15:55
*/
private static File inputStreamToFile(InputStream ins, File file) {
OutputStream os = null;
try {
os = new FileOutputStream(file);
int bytesRead;
byte[] buffer = new byte[4096];
while ((bytesRead = ins.read(buffer, 0, 4096)) != -1) {
os.write(buffer, 0, bytesRead);
}
return file;
} catch (Exception e) {
log.error(e.getMessage());
}finally {
try {
if(os != null){
os.close();
}
if(ins != null){
ins.close();
}
} catch (IOException e) {
log.error(e.getMessage());
}
}
return null;
}
/**
* 判断文件夹是否存在,不存在则创建
*/
private static File checkAndCreateFile(String targetDirectory) {
File filePath = new File(targetDirectory);
//文件夹不存在
if(!filePath.exists()){
//创建
if(!filePath.mkdir()){
log.error("创建文件夹: "+ filePath.getName() +" 失败");
throw new CustomException("创建文件夹: "+ filePath.getName() +" 失败");
}
}
return filePath;
}
/**
* 判断文件夹是否存在,不存在则创建
*/
private static File checkAndCreateFile() {
File filePath = new File(uploadPath);
//文件夹不存在
if(!filePath.exists()){
//创建
if(!filePath.mkdir()){
log.error("创建文件夹: "+ filePath.getName() +" 失败");
throw new CustomException("创建文件夹: "+ filePath.getName() +" 失败");
}
}
return filePath;
}
/**
* 截取文件名除去扩展名
* @date 2020/8/4 16:11
*/
public static String getPrefix(String fileName) {
return fileName.substring(0,fileName.lastIndexOf(".")).toLowerCase();
}
/**
* 截取文件扩展名
* @since 2020/8/4 16:11
* @author liudongxin
*/
public static String getExt(String fileName) {
return fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
}
/**
* 设根据文件类型置响应类型
* @since 2020/8/4 16:11
*/
private static String getFileContentType(String strFileExt) {
String strContentType;
if ((strFileExt == null) || ((strFileExt = strFileExt.trim().toLowerCase()).length() == 0)) {
strContentType = "text/plain";
return strContentType;
}
switch (strFileExt){
case ".sql":
strContentType = "text/txt";
break;
case ".html":
case ".htm":
strContentType = "text/html";
break;
case ".xml":
case ".xsl":
strContentType = "text/xml";
break;
case ".zip":
strContentType = "application/zip";
break;
case ".exe":
strContentType = "application/exec";
break;
case ".gif":
strContentType = "image/gif";
break;
case ".jpe":
case ".jpeg":
case ".jpg":
strContentType = "image/jpeg";
break;
case ".pdf":
strContentType = "application/pdf";
break;
case ".doc":
case ".rtf":
strContentType = "application/msword";
break;
case ".ppt":
strContentType = "application/vnd.ms-powerpoint";
break;
case ".xls":
case ".xlsx":
strContentType = "application/vnd.ms-excel";
break;
case ".ceb":
strContentType = "application/x-ceb";
break;
case ".ftl":
strContentType = "application/force-download";
break;
default:
strContentType = "application/octet-stream";
break;
}
return strContentType;
}
}