zouyu
2025-09-26 3fbbfcc8f509c352c58dc8a126220b49b72ed5a0
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
package com.xindao.ocr.swingui.swing.utils;
 
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
 
public class FileNameValidator {
    
    // Windows系统不允许出现在文件名中的字符
    private static final Set<Character> ILLEGAL_CHARACTERS;
    // Windows系统保留的文件名
    private static final Set<String> RESERVED_NAMES;
    
    static {
        // 初始化非法字符集
        ILLEGAL_CHARACTERS = new HashSet<>(Arrays.asList(
            '/', '\'', '"', '\\', '*', ':', '?', '<', '>', '|'
        ));
        
        // 初始化保留文件名称集合
        RESERVED_NAMES = new HashSet<>(Arrays.asList(
            "con", "prn", "aux", "nul",
            "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
            "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"
        ));
    }
    
    /**
     * 校验并清理文件名,使其符合Windows命名规则
     * @param fileName 原始文件名
     * @param replacement 用于替换非法字符的合法字符
     * @return 处理后的合法文件名
     */
    public static String validateAndCleanFileName(String fileName, char replacement) {
        if (fileName == null || fileName.trim().isEmpty()) {
            return "unnamed";
        }
        
        // 移除首尾空格
        String cleaned = fileName.trim();
        
        // 替换非法字符
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cleaned.length(); i++) {
            char c = cleaned.charAt(i);
            sb.append(ILLEGAL_CHARACTERS.contains(c) ? replacement : c);
        }
        cleaned = sb.toString();
        
        // 检查是否是保留文件名(不区分大小写)
        int dotIndex = cleaned.indexOf('.');
        String nameWithoutExtension = dotIndex != -1 ? cleaned.substring(0, dotIndex) : cleaned;
        if (RESERVED_NAMES.contains(nameWithoutExtension.toLowerCase())) {
            cleaned = replacement + cleaned;
        }
        
        // 处理只包含点或空格的情况
        if (cleaned.replaceAll("[./\\\\ ]", "").isEmpty()) {
            cleaned = "file" + replacement + cleaned;
        }
        
        // 处理以点结尾的情况
        while (cleaned.endsWith(".")) {
            cleaned = cleaned.substring(0, cleaned.length() - 1) + replacement;
        }
        
        // 限制文件名长度(Windows通常限制为255个字符)
        if (cleaned.length() > 255) {
            cleaned = cleaned.substring(0, 255);
        }
        
        return cleaned;
    }
    
    /**
     * 重载方法,使用下划线作为默认替换字符
     */
    public static String validateAndCleanFileName(String fileName) {
        return validateAndCleanFileName(fileName, '_');
    }
}