using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace fileFinder { public enum TaskState { Created, Work, Pause, Finished } class TaskController { private Stopwatch stopwatch = new Stopwatch(); public TaskState state { get; private set; } public TaskController() { state = TaskState.Created; } public void beginTask() { state = TaskState.Work; stopwatch.Restart(); } public void pauseTask() { state = TaskState.Pause; stopwatch.Stop(); } public void resumeTask() { state = TaskState.Work; stopwatch.Start(); } public void stopTask() { state = TaskState.Finished; stopwatch.Stop(); } public TimeSpan elapsedTime() { return stopwatch.Elapsed; } public async Task buildResultTree(SearchQueryModel query, IProgress report) { TaskController controller = this; TreeNode itemsNode = new TreeNode(); report.Report(createReport(null, "Индексирование заданного пути", 0, 0, 0)); List foundFiles = getFileList(query.fileUrl, query.fileNameQuery); report.Report(createReport(null, null, 0, 0, foundFiles.Count)); int matchingFiles = 0, processedFiles = 0; foreach (string item in foundFiles) { switch (state) { case TaskState.Finished: return null; case TaskState.Pause: report.Report(createReport((TreeNode)itemsNode.Clone(), item, matchingFiles, processedFiles, foundFiles.Count)); while (state == TaskState.Pause) Thread.Sleep(100); goto case TaskState.Work; case TaskState.Work: string[] fileLines = getFileContents(item); report.Report(createReport(null, item, matchingFiles, processedFiles, foundFiles.Count)); if ((fileLines.Length > 0) && (isFileContainQuery(fileLines, query.fileInnerQuery))) { await fillChildNode(itemsNode, item.Replace(query.fileUrl, "")); matchingFiles++; } processedFiles++; break; } } report.Report(createReport(null, "none", matchingFiles, processedFiles, foundFiles.Count)); controller.stopTask(); return itemsNode; } private ProgressReportModel createReport(TreeNode treeNode, string fileUrl, int matchingFiles, int processedFiles, int totalNumOfFiles) { ProgressReportModel prm = new ProgressReportModel(); prm.currentTreeNode = treeNode; prm.currentFileUrl = fileUrl; prm.matchingFiles = matchingFiles; prm.processedFiles = processedFiles; prm.totalNumOfFiles = totalNumOfFiles; return prm; } private List getFileList(string directory, string nameQuery) { List fileList = new List(); try { fileList = Directory.GetFiles(directory, nameQuery, SearchOption.AllDirectories).ToList(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Не удалось получить доступ к файлу/папке"); } return fileList; } private string[] getFileContents(string fileUrl) { try { return File.ReadAllLines(fileUrl, Encoding.UTF8); } catch (Exception ex) { MessageBox.Show(ex.Message, "Ошибка поиска внутри файла!"); } return null; } private bool isFileContainQuery(string[] fileLines, string query) { foreach (string item in fileLines) if (item.IndexOf(query) != -1) return true; return false; } public async Task fillChildNode(TreeNode node, String item) { int backSlashIndex = item.IndexOf("\\"); switch (backSlashIndex) { case -1: node.Nodes.Add(item, item, 2, 2); break; case 0: item = item.Remove(0, 1); await fillChildNode(node, item); break; default: String currentNodeName = item.Substring(0, backSlashIndex); int nodeIndex = node.Nodes.IndexOfKey(currentNodeName); if (nodeIndex != -1) await fillChildNode(node.Nodes[nodeIndex], item.Remove(0, backSlashIndex + 1)); else { node.Nodes.Add(currentNodeName, currentNodeName, 0, 0); nodeIndex = node.Nodes.IndexOfKey(currentNodeName); await fillChildNode(node.Nodes[nodeIndex], item.Remove(0, backSlashIndex + 1)); } break; } } public SearchQueryModel updateSearchQueryModel(string fileUrl, string fileNameQuery, string fileInnerQuery) { SearchQueryModel sqModel = new SearchQueryModel(); sqModel.fileUrl = fileUrl; sqModel.fileNameQuery = fileNameQuery; sqModel.fileInnerQuery = fileInnerQuery; return sqModel; } } }