package main import ( "fmt" "os" "path/filepath" "strings" ) const ( utf8BOMPrefix = "\xEF\xBB\xBF" // UTF-8 BOM 标记 ) func main() { dirPath := "E:\\f1\\client" // 验证目录是否存在 if info, err := os.Stat(dirPath); err != nil || !info.IsDir() { fmt.Printf("Error: %s is not a valid directory\n", dirPath) os.Exit(1) } // 构建屏蔽目录集合,加快查找速度 excludeSet := make(map[string]bool) excludeSet["Library"] = true excludeSet["Packages"] = true excludeSet["Temp"] = true excludeSet[".git"] = true // 遍历目录 err := filepath.WalkDir(dirPath, func(path string, d os.DirEntry, err error) error { if err != nil { fmt.Fprintf(os.Stderr, "Warning: cannot access %s: %v\n", path, err) return filepath.SkipDir // 跳过出错目录,而不是完全终止 } // 检查是否是需要屏蔽的目录 if d.IsDir() && excludeSet[d.Name()] { return filepath.SkipDir // 跳过当前目录及其子目录 } // 只处理 .cs 文件(不区分大小写) if !d.IsDir() && strings.EqualFold(filepath.Ext(path), ".cs") { hasBOM, err := checkUTF8WithBOM(path) if err != nil { fmt.Fprintf(os.Stderr, "Warning: cannot read file %s: %v\n", path, err) return nil } if !hasBOM { if true { // 写入模式:转换文件 if err := convertToUTF8WithBOM(path, false); err != nil { fmt.Fprintf(os.Stderr, "Error converting %s: %v\n", path, err) } else { fmt.Printf("Converted: %s\n", path) } } else { // 只读模式:仅输出路径 fmt.Println(path) } } } return nil }) if err != nil { fmt.Fprintf(os.Stderr, "Error walking directory: %v\n", err) os.Exit(1) } } // 自定义字符串 slice 类型的 flag,支持多次使用 type stringSliceFlag []string func (s *stringSliceFlag) String() string { return strings.Join(*s, ",") } func (s *stringSliceFlag) Set(value string) error { *s = append(*s, value) return nil } // checkUTF8WithBOM 检查文件是否以 UTF-8 BOM 开头 func checkUTF8WithBOM(filename string) (bool, error) { file, err := os.Open(filename) if err != nil { return false, fmt.Errorf("failed to open file: %w", err) } defer file.Close() bom := make([]byte, 3) n, err := file.Read(bom) if err != nil && err.Error() != "EOF" { return false, fmt.Errorf("failed to read file: %w", err) } if n < 3 { return false, nil } return string(bom) == utf8BOMPrefix, nil } // 将文件转换为 UTF-8 with BOM func convertToUTF8WithBOM(filename string, backup bool) error { // 读取原始文件内容 content, err := os.ReadFile(filename) if err != nil { return fmt.Errorf("failed to read file: %w", err) } // 如果文件已经是 UTF-8 with BOM,跳过 if len(content) >= 3 && string(content[:3]) == utf8BOMPrefix { return nil } // 如果需要备份,创建备份文件 if backup { backupFile := filename + ".bak" if err := os.WriteFile(backupFile, content, 0644); err != nil { return fmt.Errorf("failed to create backup: %w", err) } } // 创建临时文件 tempFile := filename + ".tmp" file, err := os.Create(tempFile) if err != nil { return fmt.Errorf("failed to create temp file: %w", err) } // 写入 BOM if _, err := file.WriteString(utf8BOMPrefix); err != nil { file.Close() os.Remove(tempFile) return fmt.Errorf("failed to write BOM: %w", err) } // 写入原始内容 if _, err := file.Write(content); err != nil { file.Close() os.Remove(tempFile) return fmt.Errorf("failed to write content: %w", err) } file.Close() // 替换原文件 if err := os.Rename(tempFile, filename); err != nil { // 如果重命名失败,尝试删除原文件再重命名 os.Remove(filename) if err := os.Rename(tempFile, filename); err != nil { return fmt.Errorf("failed to replace original file: %w", err) } } return nil }