FileUtils.java 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. package com.ruoyi.common.utils.file;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.OutputStream;
  8. import java.io.UnsupportedEncodingException;
  9. import java.net.URLEncoder;
  10. import java.nio.charset.StandardCharsets;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13. import org.apache.commons.io.FilenameUtils;
  14. import org.apache.commons.io.IOUtils;
  15. import org.apache.commons.lang3.ArrayUtils;
  16. import com.ruoyi.common.config.RuoYiConfig;
  17. import com.ruoyi.common.utils.DateUtils;
  18. import com.ruoyi.common.utils.StringUtils;
  19. import com.ruoyi.common.utils.uuid.IdUtils;
  20. /**
  21. * 文件处理工具类
  22. *
  23. * @author ruoyi
  24. */
  25. public class FileUtils
  26. {
  27. public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
  28. /**
  29. * 输出指定文件的byte数组
  30. *
  31. * @param filePath 文件路径
  32. * @param os 输出流
  33. * @return
  34. */
  35. public static void writeBytes(String filePath, OutputStream os) throws IOException
  36. {
  37. FileInputStream fis = null;
  38. try
  39. {
  40. File file = new File(filePath);
  41. if (!file.exists())
  42. {
  43. throw new FileNotFoundException(filePath);
  44. }
  45. fis = new FileInputStream(file);
  46. byte[] b = new byte[1024];
  47. int length;
  48. while ((length = fis.read(b)) > 0)
  49. {
  50. os.write(b, 0, length);
  51. }
  52. }
  53. catch (IOException e)
  54. {
  55. throw e;
  56. }
  57. finally
  58. {
  59. IOUtils.close(os);
  60. IOUtils.close(fis);
  61. }
  62. }
  63. /**
  64. * 写数据到文件中
  65. *
  66. * @param data 数据
  67. * @return 目标文件
  68. * @throws IOException IO异常
  69. */
  70. public static String writeImportBytes(byte[] data) throws IOException
  71. {
  72. return writeBytes(data, RuoYiConfig.getImportPath());
  73. }
  74. /**
  75. * 写数据到文件中
  76. *
  77. * @param data 数据
  78. * @param uploadDir 目标文件
  79. * @return 目标文件
  80. * @throws IOException IO异常
  81. */
  82. public static String writeBytes(byte[] data, String uploadDir) throws IOException
  83. {
  84. FileOutputStream fos = null;
  85. String pathName = "";
  86. try
  87. {
  88. String extension = getFileExtendName(data);
  89. pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
  90. File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
  91. fos = new FileOutputStream(file);
  92. fos.write(data);
  93. }
  94. finally
  95. {
  96. IOUtils.close(fos);
  97. }
  98. return FileUploadUtils.getPathFileName(uploadDir, pathName);
  99. }
  100. /**
  101. * 删除文件
  102. *
  103. * @param filePath 文件
  104. * @return
  105. */
  106. public static boolean deleteFile(String filePath)
  107. {
  108. boolean flag = false;
  109. File file = new File(filePath);
  110. // 路径为文件且不为空则进行删除
  111. if (file.isFile() && file.exists())
  112. {
  113. file.delete();
  114. flag = true;
  115. }
  116. return flag;
  117. }
  118. /**
  119. * 文件名称验证
  120. *
  121. * @param filename 文件名称
  122. * @return true 正常 false 非法
  123. */
  124. public static boolean isValidFilename(String filename)
  125. {
  126. return filename.matches(FILENAME_PATTERN);
  127. }
  128. /**
  129. * 检查文件是否可下载
  130. *
  131. * @param resource 需要下载的文件
  132. * @return true 正常 false 非法
  133. */
  134. public static boolean checkAllowDownload(String resource)
  135. {
  136. // 禁止目录上跳级别
  137. if (StringUtils.contains(resource, ".."))
  138. {
  139. return false;
  140. }
  141. // 检查允许下载的文件规则
  142. if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
  143. {
  144. return true;
  145. }
  146. // 不在允许下载的文件规则
  147. return false;
  148. }
  149. /**
  150. * 下载文件名重新编码
  151. *
  152. * @param request 请求对象
  153. * @param fileName 文件名
  154. * @return 编码后的文件名
  155. */
  156. public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
  157. {
  158. final String agent = request.getHeader("USER-AGENT");
  159. String filename = fileName;
  160. if (agent.contains("MSIE"))
  161. {
  162. // IE浏览器
  163. filename = URLEncoder.encode(filename, "utf-8");
  164. filename = filename.replace("+", " ");
  165. }
  166. else if (agent.contains("Firefox"))
  167. {
  168. // 火狐浏览器
  169. filename = new String(fileName.getBytes(), "ISO8859-1");
  170. }
  171. else if (agent.contains("Chrome"))
  172. {
  173. // google浏览器
  174. filename = URLEncoder.encode(filename, "utf-8");
  175. }
  176. else
  177. {
  178. // 其它浏览器
  179. filename = URLEncoder.encode(filename, "utf-8");
  180. }
  181. return filename;
  182. }
  183. /**
  184. * 下载文件名重新编码
  185. *
  186. * @param response 响应对象
  187. * @param realFileName 真实文件名
  188. * @return
  189. */
  190. public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
  191. {
  192. String percentEncodedFileName = percentEncode(realFileName);
  193. StringBuilder contentDispositionValue = new StringBuilder();
  194. contentDispositionValue.append("attachment; filename=")
  195. .append(percentEncodedFileName)
  196. .append(";")
  197. .append("filename*=")
  198. .append("utf-8''")
  199. .append(percentEncodedFileName);
  200. response.setHeader("Content-disposition", contentDispositionValue.toString());
  201. }
  202. /**
  203. * 百分号编码工具方法
  204. *
  205. * @param s 需要百分号编码的字符串
  206. * @return 百分号编码后的字符串
  207. */
  208. public static String percentEncode(String s) throws UnsupportedEncodingException
  209. {
  210. String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
  211. return encode.replaceAll("\\+", "%20");
  212. }
  213. /**
  214. * 获取图像后缀
  215. *
  216. * @param photoByte 图像数据
  217. * @return 后缀名
  218. */
  219. public static String getFileExtendName(byte[] photoByte)
  220. {
  221. String strFileExtendName = "jpg";
  222. if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
  223. && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
  224. {
  225. strFileExtendName = "gif";
  226. }
  227. else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
  228. {
  229. strFileExtendName = "jpg";
  230. }
  231. else if ((photoByte[0] == 66) && (photoByte[1] == 77))
  232. {
  233. strFileExtendName = "bmp";
  234. }
  235. else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
  236. {
  237. strFileExtendName = "png";
  238. }
  239. return strFileExtendName;
  240. }
  241. /**
  242. * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
  243. *
  244. * @param fileName 路径名称
  245. * @return 没有文件路径的名称
  246. */
  247. public static String getName(String fileName)
  248. {
  249. if (fileName == null)
  250. {
  251. return null;
  252. }
  253. int lastUnixPos = fileName.lastIndexOf('/');
  254. int lastWindowsPos = fileName.lastIndexOf('\\');
  255. int index = Math.max(lastUnixPos, lastWindowsPos);
  256. return fileName.substring(index + 1);
  257. }
  258. /**
  259. * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi
  260. *
  261. * @param fileName 路径名称
  262. * @return 没有文件路径和后缀的名称
  263. */
  264. public static String getNameNotSuffix(String fileName)
  265. {
  266. if (fileName == null)
  267. {
  268. return null;
  269. }
  270. String baseName = FilenameUtils.getBaseName(fileName);
  271. return baseName;
  272. }
  273. }