FileUtil.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * Copyright 2019-2020 Zheng Jie
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package me.zhengjie.utils;
  17. import cn.hutool.core.io.IoUtil;
  18. import cn.hutool.core.util.IdUtil;
  19. import cn.hutool.poi.excel.BigExcelWriter;
  20. import cn.hutool.poi.excel.ExcelUtil;
  21. import me.zhengjie.exception.BadRequestException;
  22. import org.apache.commons.codec.binary.Base64;
  23. import org.apache.poi.util.IOUtils;
  24. import org.apache.poi.xssf.streaming.SXSSFSheet;
  25. import org.slf4j.Logger;
  26. import org.slf4j.LoggerFactory;
  27. import org.springframework.web.multipart.MultipartFile;
  28. import javax.servlet.ServletOutputStream;
  29. import javax.servlet.http.HttpServletRequest;
  30. import javax.servlet.http.HttpServletResponse;
  31. import java.io.*;
  32. import java.security.MessageDigest;
  33. import java.text.DecimalFormat;
  34. import java.text.SimpleDateFormat;
  35. import java.util.Date;
  36. import java.util.List;
  37. import java.util.Map;
  38. /**
  39. * File工具类,扩展 hutool 工具包
  40. *
  41. * @author Zheng Jie
  42. * @date 2018-12-27
  43. */
  44. public class FileUtil extends cn.hutool.core.io.FileUtil {
  45. private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
  46. /**
  47. * 系统临时目录
  48. * <br>
  49. * windows 包含路径分割符,但Linux 不包含,
  50. * 在windows \\==\ 前提下,
  51. * 为安全起见 同意拼装 路径分割符,
  52. * <pre>
  53. * java.io.tmpdir
  54. * windows : C:\Users/xxx\AppData\Local\Temp\
  55. * linux: /temp
  56. * </pre>
  57. */
  58. public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator;
  59. /**
  60. * 定义GB的计算常量
  61. */
  62. private static final int GB = 1024 * 1024 * 1024;
  63. /**
  64. * 定义MB的计算常量
  65. */
  66. private static final int MB = 1024 * 1024;
  67. /**
  68. * 定义KB的计算常量
  69. */
  70. private static final int KB = 1024;
  71. /**
  72. * 格式化小数
  73. */
  74. private static final DecimalFormat DF = new DecimalFormat("0.00");
  75. public static final String IMAGE = "图片";
  76. public static final String TXT = "文档";
  77. public static final String MUSIC = "音乐";
  78. public static final String VIDEO = "视频";
  79. public static final String OTHER = "其他";
  80. /**
  81. * MultipartFile转File
  82. */
  83. public static File toFile(MultipartFile multipartFile) {
  84. // 获取文件名
  85. String fileName = multipartFile.getOriginalFilename();
  86. // 获取文件后缀
  87. String prefix = "." + getExtensionName(fileName);
  88. File file = null;
  89. try {
  90. // 用uuid作为文件名,防止生成的临时文件重复
  91. file = new File(SYS_TEM_DIR + IdUtil.simpleUUID() + prefix);
  92. // MultipartFile to File
  93. multipartFile.transferTo(file);
  94. } catch (IOException e) {
  95. log.error(e.getMessage(), e);
  96. }
  97. return file;
  98. }
  99. /**
  100. * 获取文件扩展名,不带 .
  101. */
  102. public static String getExtensionName(String filename) {
  103. if ((filename != null) && (filename.length() > 0)) {
  104. int dot = filename.lastIndexOf('.');
  105. if ((dot > -1) && (dot < (filename.length() - 1))) {
  106. return filename.substring(dot + 1);
  107. }
  108. }
  109. return filename;
  110. }
  111. /**
  112. * Java文件操作 获取不带扩展名的文件名
  113. */
  114. public static String getFileNameNoEx(String filename) {
  115. if ((filename != null) && (filename.length() > 0)) {
  116. int dot = filename.lastIndexOf('.');
  117. if ((dot > -1) && (dot < (filename.length()))) {
  118. return filename.substring(0, dot);
  119. }
  120. }
  121. return filename;
  122. }
  123. /**
  124. * 文件大小转换
  125. */
  126. public static String getSize(long size) {
  127. String resultSize;
  128. if (size / GB >= 1) {
  129. //如果当前Byte的值大于等于1GB
  130. resultSize = DF.format(size / (float) GB) + "GB ";
  131. } else if (size / MB >= 1) {
  132. //如果当前Byte的值大于等于1MB
  133. resultSize = DF.format(size / (float) MB) + "MB ";
  134. } else if (size / KB >= 1) {
  135. //如果当前Byte的值大于等于1KB
  136. resultSize = DF.format(size / (float) KB) + "KB ";
  137. } else {
  138. resultSize = size + "B ";
  139. }
  140. return resultSize;
  141. }
  142. /**
  143. * inputStream 转 File
  144. */
  145. static File inputStreamToFile(InputStream ins, String name){
  146. File file = new File(SYS_TEM_DIR + name);
  147. if (file.exists()) {
  148. return file;
  149. }
  150. OutputStream os = null;
  151. try {
  152. os = new FileOutputStream(file);
  153. int bytesRead;
  154. int len = 8192;
  155. byte[] buffer = new byte[len];
  156. while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
  157. os.write(buffer, 0, bytesRead);
  158. }
  159. } catch (Exception e) {
  160. e.printStackTrace();
  161. } finally {
  162. CloseUtil.close(os);
  163. CloseUtil.close(ins);
  164. }
  165. return file;
  166. }
  167. /**
  168. * 将文件名解析成文件的上传路径
  169. */
  170. public static File upload(MultipartFile file, String filePath) {
  171. Date date = new Date();
  172. SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS");
  173. String name = getFileNameNoEx(file.getOriginalFilename());
  174. String suffix = getExtensionName(file.getOriginalFilename());
  175. String nowStr = "-" + format.format(date);
  176. try {
  177. String fileName = name + nowStr + "." + suffix;
  178. String path = filePath + fileName;
  179. // getCanonicalFile 可解析正确各种路径
  180. File dest = new File(path).getCanonicalFile();
  181. // 检测是否存在目录
  182. if (!dest.getParentFile().exists()) {
  183. if (!dest.getParentFile().mkdirs()) {
  184. System.out.println("was not successful.");
  185. }
  186. }
  187. // 文件写入
  188. file.transferTo(dest);
  189. return dest;
  190. } catch (Exception e) {
  191. log.error(e.getMessage(), e);
  192. }
  193. return null;
  194. }
  195. /**
  196. * 导出excel
  197. */
  198. public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response) throws IOException {
  199. String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
  200. File file = new File(tempPath);
  201. BigExcelWriter writer = ExcelUtil.getBigWriter(file);
  202. // 一次性写出内容,使用默认样式,强制输出标题
  203. writer.write(list, true);
  204. SXSSFSheet sheet = (SXSSFSheet)writer.getSheet();
  205. //上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法
  206. sheet.trackAllColumnsForAutoSizing();
  207. //列宽自适应
  208. writer.autoSizeColumnAll();
  209. //response为HttpServletResponse对象
  210. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  211. //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
  212. response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
  213. ServletOutputStream out = response.getOutputStream();
  214. // 终止后删除临时文件
  215. file.deleteOnExit();
  216. writer.flush(out, true);
  217. //此处记得关闭输出Servlet流
  218. IoUtil.close(out);
  219. }
  220. public static String getFileType(String type) {
  221. String documents = "txt doc pdf ppt pps xlsx xls docx";
  222. String music = "mp3 wav wma mpa ram ra aac aif m4a";
  223. String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg";
  224. String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";
  225. if (image.contains(type)) {
  226. return IMAGE;
  227. } else if (documents.contains(type)) {
  228. return TXT;
  229. } else if (music.contains(type)) {
  230. return MUSIC;
  231. } else if (video.contains(type)) {
  232. return VIDEO;
  233. } else {
  234. return OTHER;
  235. }
  236. }
  237. public static void checkSize(long maxSize, long size) {
  238. // 1M
  239. int len = 1024 * 1024;
  240. if (size > (maxSize * len)) {
  241. throw new BadRequestException("文件超出规定大小");
  242. }
  243. }
  244. /**
  245. * 判断两个文件是否相同
  246. */
  247. public static boolean check(File file1, File file2) {
  248. String img1Md5 = getMd5(file1);
  249. String img2Md5 = getMd5(file2);
  250. if(img1Md5 != null){
  251. return img1Md5.equals(img2Md5);
  252. }
  253. return false;
  254. }
  255. /**
  256. * 判断两个文件是否相同
  257. */
  258. public static boolean check(String file1Md5, String file2Md5) {
  259. return file1Md5.equals(file2Md5);
  260. }
  261. private static byte[] getByte(File file) {
  262. // 得到文件长度
  263. byte[] b = new byte[(int) file.length()];
  264. InputStream in = null;
  265. try {
  266. in = new FileInputStream(file);
  267. try {
  268. System.out.println(in.read(b));
  269. } catch (IOException e) {
  270. log.error(e.getMessage(), e);
  271. }
  272. } catch (Exception e) {
  273. log.error(e.getMessage(), e);
  274. return null;
  275. } finally {
  276. CloseUtil.close(in);
  277. }
  278. return b;
  279. }
  280. private static String getMd5(byte[] bytes) {
  281. // 16进制字符
  282. char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  283. try {
  284. MessageDigest mdTemp = MessageDigest.getInstance("MD5");
  285. mdTemp.update(bytes);
  286. byte[] md = mdTemp.digest();
  287. int j = md.length;
  288. char[] str = new char[j * 2];
  289. int k = 0;
  290. // 移位 输出字符串
  291. for (byte byte0 : md) {
  292. str[k++] = hexDigits[byte0 >>> 4 & 0xf];
  293. str[k++] = hexDigits[byte0 & 0xf];
  294. }
  295. return new String(str);
  296. } catch (Exception e) {
  297. log.error(e.getMessage(), e);
  298. }
  299. return null;
  300. }
  301. /**
  302. * 下载文件
  303. *
  304. * @param request /
  305. * @param response /
  306. * @param file /
  307. */
  308. public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) {
  309. response.setCharacterEncoding(request.getCharacterEncoding());
  310. response.setContentType("application/octet-stream");
  311. FileInputStream fis = null;
  312. try {
  313. fis = new FileInputStream(file);
  314. response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
  315. IOUtils.copy(fis, response.getOutputStream());
  316. response.flushBuffer();
  317. } catch (Exception e) {
  318. log.error(e.getMessage(), e);
  319. } finally {
  320. if (fis != null) {
  321. try {
  322. fis.close();
  323. if (deleteOnExit) {
  324. file.deleteOnExit();
  325. }
  326. } catch (IOException e) {
  327. log.error(e.getMessage(), e);
  328. }
  329. }
  330. }
  331. }
  332. public static String getMd5(File file) {
  333. return getMd5(getByte(file));
  334. }
  335. /**
  336. * 将文件内容转换成Base64编码
  337. *
  338. * @param path
  339. * @return
  340. * @throws Exception
  341. */
  342. public static String encodeBase64File(String path) throws Exception {
  343. File file = new File(path);
  344. FileInputStream inputFile = new FileInputStream(file);
  345. byte[] buffer = new byte[(int) file.length()];
  346. inputFile.read(buffer);
  347. inputFile.close();
  348. return Base64.encodeBase64String(buffer);
  349. }
  350. }