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