为什么当在文件内搜索文本时,要搜索的文件很多,内存使用量会增加2GB以上?

时间:2019-04-03 10:07:25

标签: c# winforms

我不得不从任务管理器中关闭该应用程序。

例如,我正在搜索整个D:\驱动器,并且有超过400000个文件。 第一次获取文件,第二次在每个文件中搜索特定的给定字符串。

启动后台工作者:

private void startButton_Click(object sender, EventArgs e)
        {
            ListViewCostumControl.lvnf.Items.Clear();
            numberoffiles = 0;
            numberofrestrictedFiles = 0;
            numberofdirs = 0;
            label24.Text = "0";
            label1.Text = "0";
            label15.Text = "0";
            Logger.Write("Operation started");
            label21.Text = "Phase 1: Retrieving files";
            label21.Visible = true;
            startButton.Enabled = false;
            stopButton.Enabled = true;
            pauseresumeButton.Enabled = true;
            label1.Select();
            timer1.Start();
            if (!backgroundWorker1.IsBusy)
            {
                SetWorkerMode(true);
                backgroundWorker1.RunWorkerAsync();
            }
        }

在DoWork内部:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            _stopwatch.Restart();

            string[] values = textBox1.Text.Split(new string[] { ",," }, StringSplitOptions.None);
            DirSearch(textBox3.Text, textBox2.Text, values, worker, e);

            _stopwatch.Stop();
        }

DirSearch方法:

int numberofdirs = 0;
        void DirSearch(string rootDirectory, string filesExtension, string[] textToSearch, BackgroundWorker worker, DoWorkEventArgs e)
        {
            List<string> resultsoftextfound = new List<string>();
            List<string> resultsoftextfound1 = new List<string>();
            List<string> filePathList = new List<string>();
            int numberoffiles = 0;
            try
            {
                filePathList = SearchAccessibleFilesNoDistinct(rootDirectory, null,worker,e).ToList();
            }
            catch (Exception err)
            {
                string ad = err.ToString();
            }
            label21.Invoke((MethodInvoker)delegate
                    {
                        label21.Text = "Phase 2: Searching in files";
                    });

            MyProgress myp = new MyProgress();
            myp.Report4 = filePathList.Count.ToString();
            foreach (string file in filePathList)
            {
                try
                {
                    var tempFR = File.ReadAllText(file);
                    _busy.WaitOne();
                    if (worker.CancellationPending == true)
                    {
                        e.Cancel = true;
                        return;
                    }

                    bool reportedFile = false;

                    for (int i = 0; i < textToSearch.Length; i++)
                    {
                        if (tempFR.IndexOf(textToSearch[i], StringComparison.InvariantCultureIgnoreCase) >= 0)
                        {
                            resultsoftextfound.Add(file + "  " + textToSearch[i]);
                            if (!reportedFile)
                            {
                                numberoffiles++;

                                myp.Report1 = file;
                                myp.Report2 = numberoffiles.ToString();
                                myp.Report3 = textToSearch[i];
                                backgroundWorker1.ReportProgress(0, myp);
                                reportedFile = true;
                            }
                        }
                    }
                    numberofdirs++;
                    label1.Invoke((MethodInvoker)delegate
                    {
                        label1.Text = string.Format("{0}/{1}", numberofdirs, myp.Report4);
                        label1.Visible = true;
                    });
                }
                catch (Exception)
                {

                }
            }
        }

这两个递归搜索方法有点长,但是所有方法都相互连接:

int counter = 0;
        IEnumerable<string> SearchAccessibleFilesNoDistinctOnlyExtension(string root, List<string> files)
        {
            if (files == null)
                files = new List<string>();
            if (Directory.Exists(root))
            {
                foreach (var file in Directory.EnumerateFiles(root))
                {
                    string extension = Path.GetExtension(file);
                    if (!files.Contains(extension))
                    {
                        files.Add(extension);
                        counter++;
                    }
                }

                foreach (var subDir in Directory.EnumerateDirectories(root))
                {
                    try
                    {
                        SearchAccessibleFilesNoDistinctOnlyExtension(subDir, files);
                    }
                    catch (UnauthorizedAccessException)
                    {

                    }
                }
            }
            return files;
        }

        string restrictedFile = "";
        List<string> restrictedFiles = new List<string>();
        int numberofrestrictedFiles = 0;
        int numberoffiles = 0;
        IEnumerable<string> SearchAccessibleFilesNoDistinct(string root, List<string> files,BackgroundWorker worker, DoWorkEventArgs e)
        {
            _busy.WaitOne();
            if (files == null)
                files = new List<string>();
            if (Directory.Exists(root))
            {
                foreach (var file in Directory.EnumerateFiles(root))
                {
                    if (worker.CancellationPending == true)
                    {
                        e.Cancel = true;
                        return files;
                    }
                    restrictedFile = file;
                    string ext = Path.GetExtension(file);
                    if (!files.Contains(file) && (ext == "." + textBox2.Text || textBox2.Text == "*"))
                    //if (!files.Contains(file) && ext == textBox2.Text)
                    {
                        files.Add(file);
                    }
                    numberoffiles++;
                    label24.Invoke((MethodInvoker)delegate
                    {
                        label24.Text = numberoffiles.ToString();
                        label24.Visible = true;
                    });
                }
                foreach (var subDir in Directory.EnumerateDirectories(root))
                {
                    if (worker.CancellationPending == true)
                    {
                        e.Cancel = true;
                        return files;
                    }
                    try
                    {
                        SearchAccessibleFilesNoDistinct(subDir, files,worker, e);
                        //files.Add(subDir);
                    }
                    catch (UnauthorizedAccessException)
                    {
                        restrictedFiles.Add(restrictedFile);
                        numberofrestrictedFiles++;
                        label11.Invoke((MethodInvoker)delegate
                        {
                            label11.Text = numberofrestrictedFiles.ToString();
                            label11.Visible = true;
                        });
                        continue;
                    }
                }
            }
            return files;
        }

它可以很好地处理少量文件以进行搜索。 但是我也希望能够搜索大量文件。例如400000文件。问题在于,在某些时候它占用了所有RAM使用2GB的内存,甚至在某些时候接近3GB。

0 个答案:

没有答案