FileUtils.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package com.ozs.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.net.UnknownHostException;
  11. import java.nio.charset.StandardCharsets;
  12. import java.util.Base64;
  13. import java.util.LinkedList;
  14. import java.util.List;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;
  17. import com.alibaba.fastjson2.JSON;
  18. import com.ozs.common.utils.EsUtil;
  19. import com.ozs.common.utils.StringUtils;
  20. import com.ozs.common.vo.EsMessage;
  21. import com.ozs.common.vo.FileMessage;
  22. import lombok.extern.slf4j.Slf4j;
  23. import org.apache.commons.io.IOUtils;
  24. import org.apache.commons.lang3.ArrayUtils;
  25. import com.ozs.common.config.PurchaseConfig;
  26. import com.ozs.common.utils.DateUtils;
  27. import com.ozs.common.utils.uuid.IdUtils;
  28. import org.apache.commons.io.FilenameUtils;
  29. import org.elasticsearch.action.index.IndexRequest;
  30. import org.elasticsearch.action.index.IndexResponse;
  31. import org.elasticsearch.action.search.SearchResponse;
  32. import org.elasticsearch.client.RequestOptions;
  33. import org.elasticsearch.common.xcontent.XContentType;
  34. import org.elasticsearch.index.query.QueryBuilders;
  35. import org.elasticsearch.search.SearchHit;
  36. import org.elasticsearch.search.SearchHits;
  37. import org.elasticsearch.search.builder.SearchSourceBuilder;
  38. /**
  39. * 文件处理工具类
  40. *
  41. * @author ruoyi
  42. */
  43. @Slf4j
  44. public class FileUtils {
  45. public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
  46. /**
  47. * 输出指定文件的byte数组
  48. *
  49. * @param filePath 文件路径
  50. * @param os 输出流
  51. * @return
  52. */
  53. public static void writeBytes(String filePath, OutputStream os) throws IOException {
  54. FileInputStream fis = null;
  55. try {
  56. File file = new File(filePath);
  57. if (!file.exists()) {
  58. throw new FileNotFoundException(filePath);
  59. }
  60. fis = new FileInputStream(file);
  61. byte[] b = new byte[1024];
  62. int length;
  63. while ((length = fis.read(b)) > 0) {
  64. os.write(b, 0, length);
  65. }
  66. } catch (IOException e) {
  67. throw e;
  68. } finally {
  69. IOUtils.close(os);
  70. IOUtils.close(fis);
  71. }
  72. }
  73. /**
  74. * 写数据到文件中
  75. *
  76. * @param data 数据
  77. * @return 目标文件
  78. * @throws IOException IO异常
  79. */
  80. public static String writeImportBytes(byte[] data) throws IOException {
  81. return writeBytes(data, PurchaseConfig.getImportPath());
  82. }
  83. /**
  84. * 写数据到文件中
  85. *
  86. * @param data 数据
  87. * @param uploadDir 目标文件
  88. * @return 目标文件
  89. * @throws IOException IO异常
  90. */
  91. public static String writeBytes(byte[] data, String uploadDir) throws IOException {
  92. FileOutputStream fos = null;
  93. String pathName = "";
  94. try {
  95. String extension = getFileExtendName(data);
  96. pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
  97. File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
  98. fos = new FileOutputStream(file);
  99. fos.write(data);
  100. } finally {
  101. IOUtils.close(fos);
  102. }
  103. return FileUploadUtils.getPathFileName(uploadDir, pathName);
  104. }
  105. /**
  106. * 删除文件
  107. *
  108. * @param filePath 文件
  109. * @return
  110. */
  111. public static boolean deleteFile(String filePath) {
  112. boolean flag = false;
  113. File file = new File(filePath);
  114. // 路径为文件且不为空则进行删除
  115. if (file.isFile() && file.exists()) {
  116. flag = file.delete();
  117. }
  118. return flag;
  119. }
  120. /**
  121. * 文件名称验证
  122. *
  123. * @param filename 文件名称
  124. * @return true 正常 false 非法
  125. */
  126. public static boolean isValidFilename(String filename) {
  127. return filename.matches(FILENAME_PATTERN);
  128. }
  129. /**
  130. * 检查文件是否可下载
  131. *
  132. * @param resource 需要下载的文件
  133. * @return true 正常 false 非法
  134. */
  135. public static boolean checkAllowDownload(String resource) {
  136. // 禁止目录上跳级别
  137. if (StringUtils.contains(resource, "..")) {
  138. return false;
  139. }
  140. // 检查允许下载的文件规则
  141. if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) {
  142. return true;
  143. }
  144. // 不在允许下载的文件规则
  145. return false;
  146. }
  147. /**
  148. * 下载文件名重新编码
  149. *
  150. * @param request 请求对象
  151. * @param fileName 文件名
  152. * @return 编码后的文件名
  153. */
  154. public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
  155. final String agent = request.getHeader("USER-AGENT");
  156. String filename = fileName;
  157. if (agent.contains("MSIE")) {
  158. // IE浏览器
  159. filename = URLEncoder.encode(filename, "utf-8");
  160. filename = filename.replace("+", " ");
  161. } else if (agent.contains("Firefox")) {
  162. // 火狐浏览器
  163. filename = new String(fileName.getBytes(), "ISO8859-1");
  164. } else if (agent.contains("Chrome")) {
  165. // google浏览器
  166. filename = URLEncoder.encode(filename, "utf-8");
  167. } else {
  168. // 其它浏览器
  169. filename = URLEncoder.encode(filename, "utf-8");
  170. }
  171. return filename;
  172. }
  173. /**
  174. * 下载文件名重新编码
  175. *
  176. * @param response 响应对象
  177. * @param realFileName 真实文件名
  178. */
  179. public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
  180. String percentEncodedFileName = percentEncode(realFileName);
  181. StringBuilder contentDispositionValue = new StringBuilder();
  182. contentDispositionValue.append("attachment; filename=")
  183. .append(percentEncodedFileName)
  184. .append(";")
  185. .append("filename*=")
  186. .append("utf-8''")
  187. .append(percentEncodedFileName);
  188. response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
  189. response.setHeader("Content-disposition", contentDispositionValue.toString());
  190. response.setHeader("download-filename", percentEncodedFileName);
  191. }
  192. /**
  193. * 百分号编码工具方法
  194. *
  195. * @param s 需要百分号编码的字符串
  196. * @return 百分号编码后的字符串
  197. */
  198. public static String percentEncode(String s) throws UnsupportedEncodingException {
  199. String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
  200. return encode.replaceAll("\\+", "%20");
  201. }
  202. /**
  203. * 获取图像后缀
  204. *
  205. * @param photoByte 图像数据
  206. * @return 后缀名
  207. */
  208. public static String getFileExtendName(byte[] photoByte) {
  209. String strFileExtendName = "jpg";
  210. if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
  211. && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
  212. strFileExtendName = "gif";
  213. } else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
  214. strFileExtendName = "jpg";
  215. } else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
  216. strFileExtendName = "bmp";
  217. } else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
  218. strFileExtendName = "png";
  219. }
  220. return strFileExtendName;
  221. }
  222. /**
  223. * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
  224. *
  225. * @param fileName 路径名称
  226. * @return 没有文件路径的名称
  227. */
  228. public static String getName(String fileName) {
  229. if (fileName == null) {
  230. return null;
  231. }
  232. int lastUnixPos = fileName.lastIndexOf('/');
  233. int lastWindowsPos = fileName.lastIndexOf('\\');
  234. int index = Math.max(lastUnixPos, lastWindowsPos);
  235. return fileName.substring(index + 1);
  236. }
  237. /**
  238. * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi
  239. *
  240. * @param fileName 路径名称
  241. * @return 没有文件路径和后缀的名称
  242. */
  243. public static String getNameNotSuffix(String fileName) {
  244. if (fileName == null) {
  245. return null;
  246. }
  247. String baseName = FilenameUtils.getBaseName(fileName);
  248. return baseName;
  249. }
  250. /**
  251. * 上传文档到es
  252. * @param filePath
  253. * @param id 当前文件入库id
  254. */
  255. public static void uploadESFile(String filePath,String id) {
  256. File file = new File(filePath);
  257. if (!file.exists()) {
  258. System.out.println("找不到文件");
  259. }
  260. FileMessage fileM = new FileMessage();
  261. try {
  262. byte[] bytes = getContent(file);
  263. String base64 = Base64.getEncoder().encodeToString(bytes);
  264. fileM.setId(id);
  265. fileM.setName(file.getName());
  266. fileM.setContent(base64);
  267. IndexRequest indexRequest = new IndexRequest("fileindex");
  268. //上传同时,使用attachment pipline进行提取文件
  269. indexRequest.source(JSON.toJSONString(fileM), XContentType.JSON);
  270. indexRequest.setPipeline("attachment");
  271. IndexResponse indexResponse = EsUtil.esUtil.client.index(indexRequest, RequestOptions.DEFAULT);
  272. log.info("send to eSearch:" + fileM.getName());
  273. log.info("send to eSeach results:" + indexResponse);
  274. } catch (IOException e) {
  275. e.printStackTrace();
  276. }
  277. }
  278. /**
  279. * 文件转base64
  280. *
  281. * @param file
  282. * @return
  283. * @throws IOException
  284. */
  285. public static byte[] getContent(File file) throws IOException {
  286. long fileSize = file.length();
  287. if (fileSize > Integer.MAX_VALUE) {
  288. System.out.println("file too big...");
  289. return null;
  290. }
  291. FileInputStream fi = new FileInputStream(file);
  292. byte[] buffer = new byte[(int) fileSize];
  293. int offset = 0;
  294. int numRead = 0;
  295. while (offset < buffer.length
  296. && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
  297. offset += numRead;
  298. }
  299. // 确保所有数据均被读取
  300. if (offset != buffer.length) {
  301. throw new IOException("Could not completely read file "
  302. + file.getName());
  303. }
  304. fi.close();
  305. return buffer;
  306. }
  307. public static List<EsMessage> eSearch(String msg) throws UnknownHostException {
  308. //
  309. List<EsMessage> matchRsult = new LinkedList<EsMessage>();
  310. SearchSourceBuilder builder = new SearchSourceBuilder();
  311. //因为我这边实际业务需要其他字段的查询,所以进行查询的字段就比较,如果只是查询文档中内容的话,打开注释的代码,然后注释掉这行代码
  312. builder.query(QueryBuilders.multiMatchQuery(msg, "attachment.content", "name", "sfName", "createBy").analyzer("ik_smart"));
  313. //builder.query(QueryBuilders.matchQuery("attachment.content", msg).analyzer("ik_smart"));
  314. SearchResponse searchResponse = EsUtil.selectDocument("fileindex", builder);
  315. SearchHits hits = searchResponse.getHits();
  316. for (SearchHit hit : hits.getHits()) {
  317. hit.getSourceAsMap().put("msg", "");
  318. matchRsult.add(JSON.parseObject(JSON.toJSONString(hit.getSourceAsMap()),EsMessage.class));
  319. // System.out.println(hit.getSourceAsString());
  320. }
  321. System.out.println("over in the main");
  322. return matchRsult;
  323. }
  324. }