FileContainsUtil.java 8.5 KB
Newer Older
1 2
package com.kwan.springbootkwan.utils;

3
import cn.hutool.core.collection.CollectionUtil;
4 5 6 7
import cn.hutool.core.date.StopWatch;
import com.alibaba.fastjson2.JSON;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
8
import lombok.extern.slf4j.Slf4j;
9 10 11

import java.io.File;
import java.io.IOException;
12
import java.text.SimpleDateFormat;
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.Date;
16
import java.util.List;
17
import java.util.stream.Collectors;
18 19

/**
20
 * 删除博客中不存在的照片
21 22 23 24 25
 *
 * @author : qinyingjie
 * @version : 2.2.0
 * @date : 2023/2/8 10:45
 */
26
@Slf4j
27 28
public class FileContainsUtil {
    /**
29
     * 默认图片不存在
30
     */
31
    private static ThreadLocal<Boolean> IS_EXIST = ThreadLocal.withInitial(() -> false);
32 33 34 35 36
    /**
     * 图片路径
     */
    private static final String PIC_PATH = "/Users/qinyingjie/Documents/idea-workspace/blogimg/";
    /**
37
     * 博客路径1
38
     */
39
    private static final String BLOG_FOLDER1 = "/Users/qinyingjie/Documents/vscode-workspace/blog/";
40 41 42 43
    /**
     * 博客路径2
     */
    private static final String BLOG_FOLDER2 = "/Users/qinyingjie/Documents/idea-workspace/study/blog/";
44 45 46 47
    /**
     * 博客路径3
     */
    private static final String BLOG_FOLDER3 = "/Users/qinyingjie/Documents/idea-workspace/study/belle_blog/";
48
    /**
49
     * 图片白名单
50
     */
51
    private static final List<String> PIC_PATH_WHITELISTS = Arrays.asList(
52 53 54
            "http://qinyingjie.top/blogImg/image-20230324112725149.png"
            , "http://qinyingjie.top/blogImg/logo.png"
            , "http://qinyingjie.top/blogImg/image-20230601124308164.png"
55
            , "http://qinyingjie.top/blogImg/image-20230822102858692.png"
56
    );
57

58
    public static void main(String[] args) throws Exception {
59
        StopWatch stopWatch = new StopWatch();
60
        currentTime("开始时间");
61 62
        stopWatch.start("删除未用到的图片");
        //不存在的图片集合
63
        final List<String> isNotExist = new ArrayList<>();
64
        //获取所有图片名称
65
        final List<String> picNames = getPicName(PIC_PATH);
66 67
        final int size = picNames.size();
        log.info("图片总数为{}", size);
68 69
        List<List<String>> groupedPicNames = dataGroup(picNames);
        moreThread(groupedPicNames, isNotExist);
70
        log.info("不存在图片总数为{}", isNotExist.size());
71 72
        stopWatch.stop();
        //毫秒输出
73 74 75
        log.info("耗时统计信息:{}", JSON.toJSONString(stopWatch.getTaskInfo()));
        log.info("耗时秒数:{}", JSON.toJSONString(stopWatch.getTotalTimeSeconds()));
        log.info("耗时分钟数:{}", JSON.toJSONString(stopWatch.getTotalTimeSeconds() / 60));
76
        currentTime("结束时间");
77 78
    }

79 80 81 82 83 84 85 86 87
    /**
     * 多线程处理图片任务
     *
     * @param groupedPicNames
     * @param isNotExist
     */
    private static void moreThread(List<List<String>> groupedPicNames, List<String> isNotExist) {
        // 创建并启动4个线程来处理每个组的任务
        List<Thread> threads = new ArrayList<>();
88
        for (int i = 0; i < 6; i++) {
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
            final List<String> group = groupedPicNames.get(i);
            Thread thread = new Thread(() -> {
                // 在这里执行处理图片组的任务
                if (CollectionUtil.isNotEmpty(group)) {
                    for (String picName : group) {
                        // 处理图片文件 picName
                        //是白名单里面的图片,直接忽略
                        for (String picPathWhitelist : PIC_PATH_WHITELISTS) {
                            if (picPathWhitelist.contains(picName)) {
                                continue;
                            }
                        }
                        //默认不存在
                        IS_EXIST.set(false);
                        //包含某个字符串
                        try {
                            traverseFolder(BLOG_FOLDER1, picName);
                            traverseFolder(BLOG_FOLDER2, picName);
                            traverseFolder(BLOG_FOLDER3, picName);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //文件不存在
                        if (!IS_EXIST.get()) {
                            isNotExist.add(picName);
                            deletePic(PIC_PATH + picName);
                        }
                    }
                }

            });
            thread.start();
            threads.add(thread);
        }
        // 等待所有线程完成
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 数据分组
135
     * 经过测试6组和8组的时间基本一致,线程数并不是越大越好
136 137 138 139 140
     *
     * @param picNames
     * @return
     */
    private static List<List<String>> dataGroup(List<String> picNames) {
141
        int groupSize = picNames.size() / 6; // 计算每组的大小
142 143 144 145 146 147 148 149 150
        List<List<String>> groupedPicNames =
                picNames.stream()
                        .collect(Collectors.groupingBy(e -> picNames.indexOf(e) / groupSize))
                        .values()
                        .stream()
                        .collect(Collectors.toList());
        return groupedPicNames;
    }

151 152 153 154 155 156 157
    /**
     * 获取文件
     *
     * @param path
     * @param word
     * @throws IOException
     */
158
    public static void traverseFolder(String path, String word) throws Exception {
159 160 161 162 163 164 165 166
        File file = new File(path);
        if (file.exists()) {
            //获取文件夹下的文件
            File[] files = file.listFiles();
            if (null != files && files.length != 0) {
                for (File file2 : files) {
                    //是否是文件夹
                    if (file2.isDirectory()) {
167
                        traverseFolder(file2.getAbsolutePath(), word);
168
                    } else {
169 170 171
                        //包含md结尾的文件
                        if (file2.getAbsolutePath().contains(".md")) {
                            getParams(file2.getAbsolutePath(), word);
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
                        }
                    }
                }
            }
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param classPath
     * @param word
     * @throws IOException
     */
    public static void getParams(String classPath, String word) throws IOException {
        File file = new File(classPath);
        //每行作为一个字符串,存为列表元素
        List<String> strings = Files.readLines(file, Charsets.UTF_8);
        for (String string : strings) {
            //判断是否包含方法名称,即指定字符串
            if (string.contains(word)) {
                //文件存在
194
                IS_EXIST.set(true);
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
            }
        }
    }

    /**
     * 获取图片名称
     *
     * @param path
     * @return
     */
    public static List<String> getPicName(String path) {
        List<String> picNames = new ArrayList<>();
        File file = new File(path);
        if (file.exists()) {
            //获取文件夹下的文件
            File[] files = file.listFiles();
            if (null != files && files.length != 0) {
                for (File file2 : files) {
                    //是否是文件夹
                    if (!file2.isDirectory()) {
                        //包含md结尾的文件
                        final String name = file2.getName();
                        picNames.add(name);
                    }
                }
            }
        }
        return picNames;
    }

    /**
     * 删除文件
     *
     * @param picPath
     */
    public static void deletePic(String picPath) {
        File file = new File(picPath);
        try {
            file.delete();
            System.out.printf("删除文件成功:%s%n", picPath);
        } catch (Exception e) {
            System.err.printf("无法删除的路径 %s%n%s", picPath, e);
        }
    }
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253

    /**
     * 打印当前时间
     *
     * @param str
     */
    public static void currentTime(String str) {
        // 获取当前时间
        Date currentTime = new Date();
        // 创建一个格式化器以将时间转换为所需的格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 使用格式化器将时间转换为字符串并打印
        String formattedTime = dateFormat.format(currentTime);
        System.out.println(str + ":" + formattedTime);
    }
254
}