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; } private MainForm form; private TreeView currentView; public TaskController(MainForm form, TreeView viewer) { this.form = form; currentView = viewer; 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 void buildResultTree(SearchQueryModel query, IProgress report) { TaskController controller = this; report.Report(createReport("Индексирование заданного пути", 0, 0, 0)); List foundFiles = getFileList(query.fileUrl, query.fileNameQuery); report.Report(createReport(null, 0, 0, foundFiles.Count)); int matchingFiles = 0, processedFiles = 0; foreach (string item in foundFiles) { switch (state) { case TaskState.Finished: return; case TaskState.Pause: report.Report(createReport(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(item, matchingFiles, processedFiles, foundFiles.Count)); if ((fileLines.Length > 0) && (isFileContainQuery(fileLines, query.fileInnerQuery))) { await fillChildNode(currentView.Nodes, item.Replace(query.fileUrl, "")); matchingFiles++; } processedFiles++; break; } } report.Report(createReport("none", matchingFiles, processedFiles, foundFiles.Count)); controller.stopTask(); } private ProgressReportModel createReport(string fileUrl, int matchingFiles, int processedFiles, int totalNumOfFiles) { if (state == TaskState.Finished) return null; ProgressReportModel prm = new ProgressReportModel(); 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(TreeNodeCollection node, String item) { int backSlashIndex = item.IndexOf("\\"); switch (backSlashIndex) { case -1: Action refresh = () => { node.Add(item, item, 2, 2); }; try { form.Invoke(refresh); } catch { } break; case 0: item = item.Remove(0, 1); await fillChildNode(node, item); break; default: String currentNodeName = item.Substring(0, backSlashIndex); int nodeIndex = node.IndexOfKey(currentNodeName); if (nodeIndex != -1) await fillChildNode(node[nodeIndex].Nodes, item.Remove(0, backSlashIndex + 1)); else { Action refresh2 = () => { node.Add(currentNodeName, currentNodeName, 0, 0); }; try { form.Invoke(refresh2); } catch { } nodeIndex = node.IndexOfKey(currentNodeName); await fillChildNode(node[nodeIndex].Nodes, 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; } } }