FileContainsUtil.java 8.2 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
            "image-20231107143410634.png"
53
    );
54

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

76 77 78 79 80 81 82
    /**
     * 多线程处理图片任务
     *
     * @param groupedPicNames
     * @param isNotExist
     */
    private static void moreThread(List<List<String>> groupedPicNames, List<String> isNotExist) {
83
        // 创建并启动6个线程来处理每个组的任务
84
        List<Thread> threads = new ArrayList<>();
85
        for (int i = 0; i < 6; i++) {
86 87 88 89 90
            final List<String> group = groupedPicNames.get(i);
            Thread thread = new Thread(() -> {
                // 在这里执行处理图片组的任务
                if (CollectionUtil.isNotEmpty(group)) {
                    for (String picName : group) {
秦英杰 已提交
91
                        // 是白名单里面的图片,直接忽略
92
                        if (!PIC_PATH_WHITELISTS.contains(picName)) {
秦英杰 已提交
93
                            // 默认不存在
94
                            IS_EXIST.set(false);
秦英杰 已提交
95
                            // 包含某个字符串
96 97 98 99 100 101 102
                            try {
                                traverseFolder(BLOG_FOLDER1, picName);
                                traverseFolder(BLOG_FOLDER2, picName);
                                traverseFolder(BLOG_FOLDER3, picName);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
秦英杰 已提交
103
                            // 文件不存在
104 105 106
                            if (!IS_EXIST.get()) {
                                isNotExist.add(picName);
                                deletePic(PIC_PATH + picName);
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
                            }
                        }
                    }
                }
            });
            thread.start();
            threads.add(thread);
        }
        // 等待所有线程完成
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

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

143 144 145 146 147 148 149
    /**
     * 获取文件
     *
     * @param path
     * @param word
     * @throws IOException
     */
150
    public static void traverseFolder(String path, String word) throws Exception {
151 152
        File file = new File(path);
        if (file.exists()) {
秦英杰 已提交
153
            // 获取文件夹下的文件
154 155 156
            File[] files = file.listFiles();
            if (null != files && files.length != 0) {
                for (File file2 : files) {
秦英杰 已提交
157
                    // 是否是文件夹
158
                    if (file2.isDirectory()) {
159
                        traverseFolder(file2.getAbsolutePath(), word);
160
                    } else {
秦英杰 已提交
161
                        // 包含md结尾的文件
162 163
                        if (file2.getAbsolutePath().contains(".md")) {
                            getParams(file2.getAbsolutePath(), word);
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
                        }
                    }
                }
            }
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param classPath
     * @param word
     * @throws IOException
     */
    public static void getParams(String classPath, String word) throws IOException {
        File file = new File(classPath);
秦英杰 已提交
180
        // 每行作为一个字符串,存为列表元素
181 182
        List<String> strings = Files.readLines(file, Charsets.UTF_8);
        for (String string : strings) {
秦英杰 已提交
183
            // 判断是否包含方法名称,即指定字符串
184
            if (string.contains(word)) {
秦英杰 已提交
185
                // 文件存在
186
                IS_EXIST.set(true);
187 188 189 190 191 192 193 194 195 196 197 198 199 200
            }
        }
    }

    /**
     * 获取图片名称
     *
     * @param path
     * @return
     */
    public static List<String> getPicName(String path) {
        List<String> picNames = new ArrayList<>();
        File file = new File(path);
        if (file.exists()) {
秦英杰 已提交
201
            // 获取文件夹下的文件
202 203 204
            File[] files = file.listFiles();
            if (null != files && files.length != 0) {
                for (File file2 : files) {
秦英杰 已提交
205
                    // 是否是文件夹
206
                    if (!file2.isDirectory()) {
秦英杰 已提交
207
                        // 包含md结尾的文件
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
                        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);
        }
    }
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245

    /**
     * 打印当前时间
     *
     * @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);
    }
246
}