package cc.mrbird.febs.common.utils;
|
|
import cc.mrbird.febs.common.entity.FebsConstant;
|
import cn.hutool.core.lang.UUID;
|
import com.google.common.base.Preconditions;
|
import lombok.extern.slf4j.Slf4j;
|
import net.coobird.thumbnailator.Thumbnails;
|
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import javax.imageio.ImageIO;
|
import javax.servlet.http.HttpServletResponse;
|
import java.awt.image.BufferedImage;
|
import java.io.*;
|
import java.nio.file.Files;
|
import java.nio.file.Paths;
|
import java.util.Arrays;
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.zip.CRC32;
|
import java.util.zip.CheckedOutputStream;
|
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipOutputStream;
|
|
/**
|
* @author MrBird
|
*/
|
@Slf4j
|
public class FileUtil {
|
|
private static final int BUFFER = 1024 * 8;
|
|
/**
|
* 文件上传服务器本地路径
|
*/
|
public static Map<String,Object> fileUploadEsc(MultipartFile file,String resourceUrl,String resourcePath) throws IOException {
|
// 文件保存目录路径
|
String savePath = resourcePath;
|
// 文件保存目录URL
|
String saveUrl = resourceUrl;
|
// 检查目录
|
File uploadDir = new File(savePath);
|
if (!uploadDir.isDirectory()) {
|
uploadDir.mkdir();
|
}
|
// 获得文件的后缀
|
String fileName = file.getOriginalFilename();
|
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
|
//限制文件格式为图片
|
// 限制文件格式为图片
|
if (!isImage(file.getInputStream())) {
|
Map<String,Object> map = new HashMap<String,Object>();
|
map.put("code",1); // 1表示失败
|
map.put("msg","文件格式不支持"); // 提示消息
|
return map;
|
}
|
String newFileName = UUID.randomUUID().toString() + "." + fileExt;
|
if (isImage(file.getInputStream())) {
|
Thumbnails.of(file.getInputStream())
|
// 图片大小(长宽)压缩比例 从0-1,1表示原图
|
.scale(1f)
|
// 图片质量压缩比例 从0-1,越接近1质量越好
|
.outputQuality(0.9f)
|
.toOutputStream(new FileOutputStream(savePath + newFileName));
|
}
|
// else {
|
// File uploadedFile = new File(savePath, newFileName);
|
// uploadedFile.setReadable(true, false);
|
// uploadedFile.setExecutable(true, false);
|
// uploadedFile.setWritable(true, false);
|
// try {
|
// //存文件
|
// FileCopyUtils.copy(file.getBytes(), uploadedFile);
|
// file.transferTo(uploadedFile);
|
// } catch (IOException e) {
|
// e.printStackTrace();
|
// }
|
// }
|
|
String visitPath = (saveUrl + newFileName);
|
Map<String,Object> map = new HashMap<String,Object>();
|
Map<String,Object> map2 = new HashMap<String,Object>();
|
map2.put("src",visitPath);//图片url
|
map2.put("title",newFileName);//图片名称,这个会显示在输入框里
|
map.put("code",0);//0表示成功,1失败
|
map.put("msg","上传成功");//提示消息
|
map.put("data",map2);
|
return map;
|
}
|
public static boolean isImage(InputStream inputStream) {
|
BufferedImage read = null;
|
try {
|
read = ImageIO.read(inputStream);
|
} catch (IOException e) {
|
return false;
|
}
|
return read != null;
|
}
|
|
/**
|
* 压缩文件或目录
|
*
|
* @param fromPath 待压缩文件或路径
|
* @param toPath 压缩文件,如 xx.zip
|
*/
|
public static void compress(String fromPath, String toPath) throws IOException {
|
File fromFile = new File(fromPath);
|
File toFile = new File(toPath);
|
if (!fromFile.exists()) {
|
throw new FileNotFoundException(fromPath + "不存在!");
|
}
|
try (
|
FileOutputStream outputStream = new FileOutputStream(toFile);
|
CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32());
|
ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream)
|
) {
|
String baseDir = "";
|
compress(fromFile, zipOutputStream, baseDir);
|
}
|
}
|
|
/**
|
* 文件下载
|
*
|
* @param filePath 待下载文件路径
|
* @param fileName 下载文件名称
|
* @param delete 下载后是否删除源文件
|
* @param response HttpServletResponse
|
* @throws Exception Exception
|
*/
|
public static void download(String filePath, String fileName, Boolean delete, HttpServletResponse response) throws Exception {
|
File file = new File(filePath);
|
if (!file.exists()) {
|
throw new Exception("文件未找到");
|
}
|
|
String fileType = getFileType(file);
|
if (!fileTypeIsValid(fileType)) {
|
throw new Exception("暂不支持该类型文件下载");
|
}
|
response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(fileName, "utf-8"));
|
response.setContentType("multipart/form-data");
|
response.setCharacterEncoding("utf-8");
|
try (InputStream inputStream = new FileInputStream(file); OutputStream os = response.getOutputStream()) {
|
byte[] b = new byte[2048];
|
int length;
|
while ((length = inputStream.read(b)) > 0) {
|
os.write(b, 0, length);
|
}
|
} finally {
|
if (delete) {
|
delete(filePath);
|
}
|
}
|
}
|
|
/**
|
* 递归删除文件或目录
|
*
|
* @param filePath 文件或目录
|
*/
|
public static void delete(String filePath) {
|
File file = new File(filePath);
|
if (file.isDirectory()) {
|
File[] files = file.listFiles();
|
if (files != null) {
|
Arrays.stream(files).forEach(f -> delete(f.getPath()));
|
}
|
}
|
try {
|
Files.delete(Paths.get(filePath));
|
} catch (IOException e) {
|
log.error("删除失败", e);
|
}
|
}
|
|
/**
|
* 获取文件类型
|
*
|
* @param file 文件
|
* @return 文件类型
|
* @throws Exception Exception
|
*/
|
private static String getFileType(File file) throws Exception {
|
Preconditions.checkNotNull(file);
|
if (file.isDirectory()) {
|
throw new Exception("file不是文件");
|
}
|
String fileName = file.getName();
|
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
}
|
|
|
/**
|
* 校验文件类型是否是允许下载的类型
|
* (出于安全考虑:https://github.com/wuyouzhuguli/FEBS-Shiro/issues/40)
|
*
|
* @param fileType fileType
|
* @return Boolean
|
*/
|
private static Boolean fileTypeIsValid(String fileType) {
|
Preconditions.checkNotNull(fileType);
|
fileType = StringUtils.lowerCase(fileType);
|
return ArrayUtils.contains(FebsConstant.VALID_FILE_TYPE, fileType);
|
}
|
|
private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException {
|
if (file.isDirectory()) {
|
compressDirectory(file, zipOut, baseDir);
|
} else {
|
compressFile(file, zipOut, baseDir);
|
}
|
}
|
|
private static void compressDirectory(File dir, ZipOutputStream zipOut, String baseDir) throws IOException {
|
File[] files = dir.listFiles();
|
if (files != null && ArrayUtils.isNotEmpty(files)) {
|
for (File file : files) {
|
compress(file, zipOut, baseDir + dir.getName() + "/");
|
}
|
}
|
}
|
|
private static void compressFile(File file, ZipOutputStream zipOut, String baseDir) throws IOException {
|
if (!file.exists()) {
|
return;
|
}
|
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
|
ZipEntry entry = new ZipEntry(baseDir + file.getName());
|
zipOut.putNextEntry(entry);
|
int count;
|
byte[] data = new byte[BUFFER];
|
while ((count = bis.read(data, 0, BUFFER)) != -1) {
|
zipOut.write(data, 0, count);
|
}
|
}
|
}
|
}
|