using hyjiacan.py4n; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace DH.Commons.Enums { public static class FileHelper { /// /// 清理两个文件夹中的文件,保留文件名交集部分,其余文件删除。 /// /// 图片文件夹路径 /// 标签文件夹路径 public static void CleanupFolders(string imagesFolder, string labelsFolder) { if (!Directory.Exists(imagesFolder)) { Console.WriteLine($"Images folder does not exist: {imagesFolder}"); return; } if (!Directory.Exists(labelsFolder)) { Console.WriteLine($"Labels folder does not exist: {labelsFolder}"); return; } // 获取文件名(不包含扩展名) var imageFiles = Directory.GetFiles(imagesFolder) .Select(Path.GetFileNameWithoutExtension) .ToHashSet(); var labelFiles = Directory.GetFiles(labelsFolder) .Select(Path.GetFileNameWithoutExtension) .ToHashSet(); // 计算交集 var commonFiles = imageFiles.Intersect(labelFiles); // 删除 images 文件夹中不在交集中的文件 foreach (var imagePath in Directory.GetFiles(imagesFolder)) { string fileNameWithoutExt = Path.GetFileNameWithoutExtension(imagePath); if (!commonFiles.Contains(fileNameWithoutExt)) { File.Delete(imagePath); Console.WriteLine($"Deleted image file: {imagePath}"); } } // 删除 labels 文件夹中不在交集中的文件 foreach (var labelPath in Directory.GetFiles(labelsFolder)) { string fileNameWithoutExt = Path.GetFileNameWithoutExtension(labelPath); if (!commonFiles.Contains(fileNameWithoutExt)) { File.Delete(labelPath); Console.WriteLine($"Deleted label file: {labelPath}"); } } Console.WriteLine("Folders cleaned successfully!"); } /// /// 获取文件夹中所有图片文件的个数 /// /// 目标文件夹路径 /// 是否包含子文件夹,默认不包含 /// 图片文件总数 public static int CountImageFiles(string folderPath, bool includeSubdirectories = false) { if (!Directory.Exists(folderPath)) { throw new DirectoryNotFoundException($"The folder '{folderPath}' does not exist."); } // 支持的图片格式 string[] imageExtensions = { "*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif" }; // 搜索选项 SearchOption searchOption = includeSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; int fileCount = 0; foreach (var ext in imageExtensions) { fileCount += Directory.GetFiles(folderPath, ext, searchOption).Length; } return fileCount; } /// /// 删除一个目录所有子目录和文件 /// /// public static void DeleteDirectoryAndContents(string path) { // 确保目录存在 if (Directory.Exists(path)) { // 删除目录中的文件 string[] files = Directory.GetFiles(path); foreach (var file in files) { File.Delete(file); Console.WriteLine($"文件已删除: {file}"); } // 删除目录中的子目录 string[] directories = Directory.GetDirectories(path); foreach (var directory in directories) { DeleteDirectoryAndContents(directory); // 递归删除子目录 } // 删除空目录 Directory.Delete(path); Console.WriteLine($"目录已删除: {path}"); } else { Console.WriteLine("目录不存在!"); } } /// /// 将一个文件夹中的所有图片文件和 JSON 文件复制到另一个文件夹中 /// /// /// public static void CopyImageAndJsonFiles(string sourceDirectory, string destinationDirectory) { // 确保目标文件夹存在,如果不存在则创建它 if (!Directory.Exists(destinationDirectory)) { Directory.CreateDirectory(destinationDirectory); } // 获取源文件夹中的所有图片文件和 JSON 文件 string[] imageFiles = Directory.GetFiles(sourceDirectory, "*.*") .Where(file => file.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".gif", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".tiff", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".webp", StringComparison.OrdinalIgnoreCase)) .ToArray(); string[] jsonFiles = Directory.GetFiles(sourceDirectory, "*.json"); // 合并图片文件和 JSON 文件 string[] filesToCopy = imageFiles.Concat(jsonFiles).ToArray(); foreach (string file in filesToCopy) { try { // 获取文件名 string fileName = Path.GetFileName(file); // 拼接目标文件的完整路径 string destinationFile = Path.Combine(destinationDirectory, fileName); // 如果目标文件已存在,可以选择覆盖或跳过(这里我们选择跳过) if (File.Exists(destinationFile)) { Console.WriteLine($"文件 {fileName} 已存在,跳过复制."); continue; } // 复制文件 File.Copy(file, destinationFile); Console.WriteLine($"文件 {fileName} 已成功复制到 {destinationDirectory}"); } catch (Exception ex) { Console.WriteLine($"复制文件 {file} 时出错: {ex.Message}"); } } } /// /// 遍历图片文件夹,检查对应的标签文件夹中是否有同名的 .txt 文件。 /// 如果没有,则创建一个空的 .txt 文件。 /// /// 图片文件夹路径 /// 标签文件夹路径 public static void ProcessImageFiles(string imagesDirectory, string labelsDirectory) { // 检查 images 目录是否存在 if (!Directory.Exists(imagesDirectory)) { throw new DirectoryNotFoundException($"目录 {imagesDirectory} 不存在."); } // 检查 labels 目录是否存在,如果不存在则创建 if (!Directory.Exists(labelsDirectory)) { Directory.CreateDirectory(labelsDirectory); Console.WriteLine($"目录 {labelsDirectory} 已创建."); } // 获取 images 目录中的所有文件(包括图片文件) string[] imageFiles = Directory.GetFiles(imagesDirectory, "*.*", SearchOption.TopDirectoryOnly); string[] validExtensions = { ".jpg", ".jpeg", ".png", ".bmp", ".gif" }; // 支持的图片格式 foreach (var imageFile in imageFiles) { // 检查文件扩展名是否为支持的图片格式 string extension = Path.GetExtension(imageFile).ToLower(); if (Array.Exists(validExtensions, ext => ext == extension)) { // 获取图片文件的文件名(不包括扩展名) string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(imageFile); // 生成对应的 txt 文件路径 string labelFilePath = Path.Combine(labelsDirectory, fileNameWithoutExtension + ".txt"); // 如果该 txt 文件不存在,则创建一个空白 txt 文件 if (!File.Exists(labelFilePath)) { try { File.WriteAllText(labelFilePath, string.Empty); // 创建空白 txt 文件 Console.WriteLine($"创建空白文件: {labelFilePath}"); } catch (Exception ex) { Console.WriteLine($"无法创建文件 {labelFilePath}: {ex.Message}"); } } } } } // 封装的函数:删除没有对应 JSON 文件的图片 public static void DeleteUnmatchedImages(string labelsFolderPath, string imagesFolderPath) { try { // 获取 labels 文件夹中的所有 JSON 文件名(去除扩展名) string[] jsonFiles = Directory.GetFiles(labelsFolderPath, "*.txt"); HashSet jsonFileNames = new HashSet(); foreach (string jsonFile in jsonFiles) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(jsonFile); jsonFileNames.Add(fileNameWithoutExtension); } // 获取 images 文件夹中的所有图片文件 string[] imageFiles = Directory.GetFiles(imagesFolderPath); // 遍历图片文件,检查是否有对应的 JSON 文件 foreach (string imageFile in imageFiles) { string imageFileNameWithoutExtension = Path.GetFileNameWithoutExtension(imageFile); // 如果图片文件名不在 labels 文件夹的 JSON 文件名集合中,则删除该图片 if (!jsonFileNames.Contains(imageFileNameWithoutExtension)) { try { File.Delete(imageFile); // 删除图片 Console.WriteLine($"已删除图片: {Path.GetFileName(imageFile)}"); } catch (Exception ex) { Console.WriteLine($"删除文件 {Path.GetFileName(imageFile)} 时出错: {ex.Message}"); } } else { Console.WriteLine($"图片 {Path.GetFileName(imageFile)} 有对应的 JSON 文件,不删除。"); } } } catch (Exception ex) { Console.WriteLine($"操作失败: {ex.Message}"); } } /// /// 将 List 保存到指定文件中,格式为 "项,标签"。 /// 标签是根据项的索引生成的。 /// /// 要保存的字符串列表 /// 保存文件的路径 public static void SaveItemsToFile(List items, string filePath) { // 使用 StreamWriter 写入文件 using (StreamWriter writer = new StreamWriter(filePath)) { // 遍历 items 列表 for (int i = 0; i < items.Count; i++) { // 写入每一行,格式为 "项, 标签" writer.WriteLine($"{items[i]},{i}"); } } } public static void SaveItemsToFile(HashSet items, string filePath) { // 使用 StreamWriter 写入文件 using (StreamWriter writer = new StreamWriter(filePath)) { // 遍历 HashSet int i = 0; foreach (string item in items) { // 写入每一行,格式为 "项, 标签" writer.WriteLine($"{item},{i}"); // 假设使用 item 的长度作为标签 i++; } } } static List FileList = new List(); /// /// 递归获取指定文件夹下所有文件 /// /// /// public static List GetAllFiles(DirectoryInfo dir) { FileInfo[] allFile = dir.GetFiles(); foreach (FileInfo fi in allFile) { FileList.Add(new FileInformation { FileName = fi.Name, FilePath = fi.FullName }); } DirectoryInfo[] allDir = dir.GetDirectories(); foreach (DirectoryInfo d in allDir) { GetAllFiles(d); } return FileList; } /// /// 判断字符串是否纯字母 /// /// /// public static bool IsAlphabetOnly(string input) { return Regex.IsMatch(input, "^[a-zA-Z]+$"); } /// /// 判断字符串是否仅包含大小写字母和数字 /// /// 待判断的字符串 /// 如果字符串仅包含字母和数字,返回 true;否则返回 false public static bool IsAlphaNumericOnly(string input) { return Regex.IsMatch(input, "^[a-zA-Z0-9]+$"); } public static string ConvertHanzitoPinyinWithNumbers(string input) { // 正则表达式匹配汉字 string pattern = @"[\u4e00-\u9fa5]"; Regex regex = new Regex(pattern); StringBuilder result = new StringBuilder(); int lastIndex = 0; foreach (Match match in regex.Matches(input)) { // 将非汉字部分保留为原样 result.Append(input.Substring(lastIndex, match.Index - lastIndex)); // 获取汉字并转换为拼音 string hanzi = match.Value; string pinyin = ConvertHanziToPinyin(hanzi); // 将拼音追加到结果中 result.Append(pinyin); lastIndex = match.Index + match.Length; } // 添加最后的非汉字部分 result.Append(input.Substring(lastIndex)); return result.ToString(); } public static string ConvertHanziToPinyin(string hanzi) { // 设置拼音格式:去掉音调,拼音小写,ü保持为u: PinyinFormat format = PinyinFormat.WITHOUT_TONE | PinyinFormat.LOWERCASE | PinyinFormat.WITH_U_AND_COLON; // 获取拼音数组 List pinyinItems = Pinyin4Net.GetPinyinArray(hanzi, format); StringBuilder pinyinBuilder = new StringBuilder(); foreach (var item in pinyinItems) { // 处理多音字:默认取第一个拼音 if (item.Count > 0) { string pinyin = item[0]; // 特殊处理ü的情况 pinyin = pinyin.Replace("u:", "v"); // 将u:转为v,这是常见的拼音表示法 pinyinBuilder.Append(pinyin); } } return pinyinBuilder.ToString(); } /// /// 汉字拼音转化 /// /// /// //public static string ConvertHanzitoPinyin(string hanzi) //{ // PinyinFormat format = PinyinFormat.WITHOUT_TONE | PinyinFormat.LOWERCASE | PinyinFormat.WITH_U_UNICODE; // // string hanzi = defectRow.LabelDescription; // List pylist = Pinyin4Net.GetPinyinArray(hanzi, format); // // 提取所有拼音并合并为一个字符串 // List pinyinStrings = new List(); // foreach (var item in pylist) // { // // 将PinyinItem中的每个拼音(List)合并为一个字符串 // string joinedPinyin = string.Join("", item); // 这里的item就是一个List,其中存储了拼音 // pinyinStrings.Add(joinedPinyin); // 添加合并后的拼音 // } // // 合并所有拼音为一个字符串 // string allPinyin = string.Join("", pinyinStrings); // return allPinyin; //} /// /// 递归获取指定文件夹下所有文件 /// /// /// public static List GetAllFiles(string dir) { DirectoryInfo directoryInfo = new(dir); return GetAllFiles(directoryInfo); } public static string OpenSlectDirDialog(string dirpath = "") { FolderBrowserDialog fbd = new FolderBrowserDialog(); fbd.InitialDirectory = dirpath; if (fbd.ShowDialog() == DialogResult.OK) { string targetDirPath = fbd.SelectedPath; if (Directory.Exists(targetDirPath)) { return targetDirPath; } else return string.Empty; //ImportDirImages(targetDirPath); } else return string.Empty; } public static string OpenSlectfileDialog(string dirpath = "") { // 创建并配置 OpenFileDialog 实例 OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = "选择文件"; // 对话框标题 openFileDialog.Filter = "所有文件 (*.pt)|*.*"; // 允许选择任何类型的文件 openFileDialog.InitialDirectory = @"C:\"; // 初始显示目录,可以根据需要修改 // 显示对话框 if (openFileDialog.ShowDialog() == DialogResult.OK) { // 获取选中的文件路径 string selectedFilePath = openFileDialog.FileName; Console.WriteLine("您选择的文件路径是: " + selectedFilePath); return selectedFilePath; } else { Console.WriteLine("没有选择任何文件。"); return string.Empty; MessageBox.Show("没有选择任何文件。"); } } } public class FileInformation { public string FileName { get; set; } public string FilePath { get; set; } } }