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 ILLEGAL_CHARACTERS; // Windows系统保留的文件名 private static final Set RESERVED_NAMES; static { // 初始化非法字符集 ILLEGAL_CHARACTERS = new HashSet<>(Arrays.asList( '/', '\'', '"', '\\', '*', ':', '?', '<', '>', '|','\n' )); // 初始化保留文件名称集合 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, '_'); } }