无关风月
2024-12-25 042fbcd557ef21ab256a542f1fef039269684340
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
package com.jilongda.optometrist.utils;
 
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
 
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class FileUtils {
 
    public static final int cache = 10 * 1024;
    /**
     * 根据url下载文件,保存到filepath中
     *
     * @param url 文件的url
     * @param diskUrl 本地存储路径
     * @return
     */
    public static String download(String url, String diskUrl) {
        String filepath = "";
        String filename = "";
        try {
            HttpClient client = HttpClients.createDefault();
            HttpGet httpget = new HttpGet(url);
            // 加入Referer,防止防盗链
            httpget.setHeader("Referer", url);
            HttpResponse response = client.execute(httpget);
            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();
            if (StringUtils.isBlank(filepath)){
                Map<String,String> map = getFilePath(response,url,diskUrl);
                filepath = map.get("filepath");
                filename = map.get("filename");
            }
            File file = new File(filepath);
            file.getParentFile().mkdirs();
            FileOutputStream fileout = new FileOutputStream(file);
            byte[] buffer = new byte[cache];
            int ch = 0;
            while ((ch = is.read(buffer)) != -1) {
                fileout.write(buffer, 0, ch);
            }
            is.close();
            fileout.flush();
            fileout.close();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return filename;
    }
 
    /**
     * 根据contentType 获取对应的后缀 (列出常用的ContentType对应的后缀)
     *
     * @param contentType
     * @return
     */
    static String getContentType(String contentType){
        HashMap<String, String> map = new HashMap<String, String>() {
            {
                put("application/msword", ".doc");
                put("image/jpeg", ".jpeg");
                put("application/x-jpg", ".jpg");
                put("video/mpeg4", ".mp4");
                put("application/pdf", ".pdf");
                put("application/x-png", ".png");
                put("application/x-ppt", ".ppt");
                put("application/postscript", ".ps");
                put("application/vnd.android.package-archive", ".apk");
                put("video/avi", ".avi");
                put("text/html", ".htm");
                put("image/png", ".png");
                put("application/x-png", ".png");
                put("audio/mpeg", ".mp3");
                put("image/gif", ".gif");
            }
        };
        return map.get(contentType);
 
    }
 
    /**
     * 获取response要下载的文件的默认路径
     *
     * @param response
     * @return
     */
    public static Map<String,String> getFilePath(HttpResponse response, String url, String diskUrl) {
        Map<String,String> map = new HashMap<>();
        String filepath = diskUrl;
        String filename = getFileName(response, url);
        String contentType = response.getEntity().getContentType().getValue();
        if(StringUtils.isNotEmpty(contentType)){
            // 获取后缀
            String suffix = getContentType(contentType);
            String regEx = ".+(.+)$";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(filename);
            if (!m.find()) {
                // 如果正则匹配后没有后缀,则需要通过response中的ContentType的值进行匹配
                if(StringUtils.isNotBlank(suffix)){
                    filename = filename + suffix;
                }
            }else{
                if(filename.length()>20){
                    filename = getRandomFileName() + suffix;
                }
            }
        }
        if (filename != null) {
            filepath += filename;
        } else {
            filepath += getRandomFileName();
        }
        map.put("filename", filename);
        map.put("filepath", filepath);
        return map;
    }
 
    /**
     * 获取response header中Content-Disposition中的filename值
     * @param response
     * @param url
     * @return
     */
    public static String getFileName(HttpResponse response,String url) {
        Header contentHeader = response.getFirstHeader("Content-Disposition");
        String filename = null;
        if (contentHeader != null) {
            // 如果contentHeader存在
            HeaderElement[] values = contentHeader.getElements();
            if (values.length == 1) {
                NameValuePair param = values[0].getParameterByName("filename");
                if (param != null) {
                    try {
                        filename = param.getValue();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }else{
            // 正则匹配后缀
            filename = getSuffix(url);
        }
 
        return filename;
    }
 
    /**
     * 获取随机文件名
     *
     * @return
     */
    public static String getRandomFileName() {
        return String.valueOf(System.currentTimeMillis());
    }
 
    /**
     * 获取文件名后缀
     * @param url
     * @return
     */
    public static String getSuffix(String url) {
        // 正则表达式“.+/(.+)$”的含义就是:被匹配的字符串以任意字符序列开始,后边紧跟着字符“/”,
        // 最后以任意字符序列结尾,“()”代表分组操作,这里就是把文件名做为分组,匹配完毕我们就可以通过Matcher
        // 类的group方法取到我们所定义的分组了。需要注意的这里的分组的索引值是从1开始的,所以取第一个分组的方法是m.group(1)而不是m.group(0)。
        String regEx = ".+/(.+)$";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(url);
        if (!m.find()) {
            // 格式错误,则随机生成个文件名
            return String.valueOf(System.currentTimeMillis());
        }
        return m.group(1);
 
    }
 
 
    /**
     * 下载ZIP压缩包(会对下载后的压缩包进行删除)
     *
     * @param file     zip压缩包文件
     * @param response 响应
     * @author liukai
     */
    public static void downloadZip(File file, HttpServletResponse response) {
        OutputStream toClient = null;
        try {
            // 以流的形式下载文件。
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            toClient = new BufferedOutputStream(response.getOutputStream());
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
            toClient.write(buffer);
            toClient.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (toClient != null) {
                try {
                    toClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //删除改临时zip包(此zip包任何时候都不需要保留,因为源文件随时可以再次进行压缩生成zip包)
//            file.delete();
        }
    }
 
 
    public static Boolean deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
            System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确");
            return false;
        }
        //获取目录下子文件
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f : files) {
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()) {
                //递归删除目录下的文件
                deleteFile(f);
            } else {
                //文件删除
                f.delete();
                //打印文件名
                System.out.println("文件名:" + f.getName());
            }
        }
        //文件夹删除
        file.delete();
        System.out.println("目录名:" + file.getName());
        return true;
    }
}