FileUtil.java 12 KB

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