|
@@ -1,11 +1,19 @@
|
|
|
package com.vber.common.utils.file;
|
|
package com.vber.common.utils.file;
|
|
|
|
|
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
|
|
+import com.vber.common.config.VberConfig;
|
|
|
|
|
+import com.vber.common.utils.DateUtils;
|
|
|
|
|
+import com.vber.common.utils.StringUtils;
|
|
|
import lombok.AccessLevel;
|
|
import lombok.AccessLevel;
|
|
|
import lombok.NoArgsConstructor;
|
|
import lombok.NoArgsConstructor;
|
|
|
|
|
+import org.apache.commons.io.FilenameUtils;
|
|
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
|
|
|
+import org.apache.commons.lang3.ArrayUtils;
|
|
|
|
|
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
-import java.io.UnsupportedEncodingException;
|
|
|
|
|
|
|
+import java.io.*;
|
|
|
import java.net.URLEncoder;
|
|
import java.net.URLEncoder;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
|
|
@@ -15,6 +23,188 @@ import java.nio.charset.StandardCharsets;
|
|
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
|
public class FileUtils extends FileUtil {
|
|
public class FileUtils extends FileUtil {
|
|
|
|
|
|
|
|
|
|
+ public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 输出指定文件的byte数组
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param filePath 文件路径
|
|
|
|
|
+ * @param os 输出流
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void writeBytes(String filePath, OutputStream os) throws IOException {
|
|
|
|
|
+ FileInputStream fis = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ File file = new File(filePath);
|
|
|
|
|
+ if (!file.exists()) {
|
|
|
|
|
+ throw new FileNotFoundException(filePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ fis = new FileInputStream(file);
|
|
|
|
|
+ byte[] b = new byte[1024];
|
|
|
|
|
+ int length;
|
|
|
|
|
+ while ((length = fis.read(b)) > 0) {
|
|
|
|
|
+ os.write(b, 0, length);
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ IOUtils.close(os);
|
|
|
|
|
+ IOUtils.close(fis);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 写数据到文件中
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data 数据
|
|
|
|
|
+ * @return 目标文件
|
|
|
|
|
+ * @throws IOException IO异常
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String writeImportBytes(byte[] data) throws IOException {
|
|
|
|
|
+ return writeFileBytes(data, VberConfig.getImportPath());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 写数据到文件中
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data 数据
|
|
|
|
|
+ * @param uploadDir 目标文件
|
|
|
|
|
+ * @return 目标文件
|
|
|
|
|
+ * @throws IOException IO异常
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String writeFileBytes(byte[] data, String uploadDir) throws IOException {
|
|
|
|
|
+ FileOutputStream fos = null;
|
|
|
|
|
+ String pathName;
|
|
|
|
|
+ try {
|
|
|
|
|
+ String extension = getFileExtendName(data);
|
|
|
|
|
+ pathName = DateUtils.datePath() + "/" + IdUtil.fastUUID() + "." + extension;
|
|
|
|
|
+ File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
|
|
|
|
|
+ fos = new FileOutputStream(file);
|
|
|
|
|
+ fos.write(data);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ IOUtils.close(fos);
|
|
|
|
|
+ }
|
|
|
|
|
+ return FileUploadUtils.getPathFileName(uploadDir, pathName);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 删除文件
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param filePath 文件
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean deleteFile(String filePath) {
|
|
|
|
|
+ boolean flag = false;
|
|
|
|
|
+ File file = new File(filePath);
|
|
|
|
|
+ // 路径为文件且不为空则进行删除
|
|
|
|
|
+ if (file.isFile() && file.exists()) {
|
|
|
|
|
+ flag = file.delete();
|
|
|
|
|
+ }
|
|
|
|
|
+ return flag;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 文件名称验证
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param filename 文件名称
|
|
|
|
|
+ * @return true 正常 false 非法
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean isValidFilename(String filename) {
|
|
|
|
|
+ return filename.matches(FILENAME_PATTERN);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查文件是否可下载
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param resource 需要下载的文件
|
|
|
|
|
+ * @return true 正常 false 非法
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean checkAllowDownload(String resource) {
|
|
|
|
|
+ // 禁止目录上跳级别
|
|
|
|
|
+ if (StringUtils.contains(resource, "..")) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查允许下载的文件规则
|
|
|
|
|
+ return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource));
|
|
|
|
|
+
|
|
|
|
|
+ // 不在允许下载的文件规则
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 下载文件名重新编码
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param request 请求对象
|
|
|
|
|
+ * @param fileName 文件名
|
|
|
|
|
+ * @return 编码后的文件名
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
|
|
|
|
|
+ final String agent = request.getHeader("USER-AGENT");
|
|
|
|
|
+ String filename = fileName;
|
|
|
|
|
+ if (agent.contains("MSIE")) {
|
|
|
|
|
+ // IE浏览器
|
|
|
|
|
+ filename = URLEncoder.encode(filename, "utf-8");
|
|
|
|
|
+ filename = filename.replace("+", " ");
|
|
|
|
|
+ } else if (agent.contains("Firefox")) {
|
|
|
|
|
+ // 火狐浏览器
|
|
|
|
|
+ filename = new String(fileName.getBytes(), "ISO8859-1");
|
|
|
|
|
+ } else if (agent.contains("Chrome")) {
|
|
|
|
|
+ // google浏览器
|
|
|
|
|
+ filename = URLEncoder.encode(filename, "utf-8");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 其它浏览器
|
|
|
|
|
+ filename = URLEncoder.encode(filename, "utf-8");
|
|
|
|
|
+ }
|
|
|
|
|
+ return filename;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取图像后缀
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param photoByte 图像数据
|
|
|
|
|
+ * @return 后缀名
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String getFileExtendName(byte[] photoByte) {
|
|
|
|
|
+ String strFileExtendName = "jpg";
|
|
|
|
|
+ if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
|
|
|
|
|
+ && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
|
|
|
|
|
+ strFileExtendName = "gif";
|
|
|
|
|
+ } else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
|
|
|
|
|
+ strFileExtendName = "jpg";
|
|
|
|
|
+ } else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
|
|
|
|
|
+ strFileExtendName = "bmp";
|
|
|
|
|
+ } else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
|
|
|
|
|
+ strFileExtendName = "png";
|
|
|
|
|
+ }
|
|
|
|
|
+ return strFileExtendName;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取文件名称 /profile/upload/2022/04/16/vber.png -- vber.png
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param fileName 路径名称
|
|
|
|
|
+ * @return 没有文件路径的名称
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String getName(String fileName) {
|
|
|
|
|
+ if (fileName == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ int lastUnixPos = fileName.lastIndexOf('/');
|
|
|
|
|
+ int lastWindowsPos = fileName.lastIndexOf('\\');
|
|
|
|
|
+ int index = Math.max(lastUnixPos, lastWindowsPos);
|
|
|
|
|
+ return fileName.substring(index + 1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取不带后缀文件名称 /profile/upload/2022/04/16/vber.png -- vber
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param fileName 路径名称
|
|
|
|
|
+ * @return 没有文件路径和后缀的名称
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String getNameNotSuffix(String fileName) {
|
|
|
|
|
+ if (fileName == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return FilenameUtils.getBaseName(fileName);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 下载文件名重新编码
|
|
* 下载文件名重新编码
|
|
|
*
|
|
*
|
|
@@ -46,4 +236,6 @@ public class FileUtils extends FileUtil {
|
|
|
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
|
|
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
|
|
|
return encode.replaceAll("\\+", "%20");
|
|
return encode.replaceAll("\\+", "%20");
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
}
|
|
}
|