在文件中搜索文本时,我多次得到相同的结果?

时间:2016-06-15 21:49:07

标签: c# .net winforms

这是我用来搜索文件中的文字的方法。

int tfiles = 0;
        int tdirs = 0;
        void WalkDirectoryTree(System.IO.DirectoryInfo root, string filesExtension, string textToSearch)
        {
            System.IO.FileInfo[] files = null;
            System.IO.DirectoryInfo[] subDirs = null;
            string[] workerResult = new string[4];
            try
            {
                files = root.GetFiles(filesExtension);
                tdirs ++;
                workerResult[1] = root.FullName;
                workerResult[3] = tdirs.ToString();
                backgroundWorker1.ReportProgress(0,workerResult);
            }
            catch (UnauthorizedAccessException e)
            {

            }

            catch (System.IO.DirectoryNotFoundException e)
            {

            }

            if (files != null)
            {
                foreach (System.IO.FileInfo fi in files)
                {
                    tfiles += files.Length;
                    if (files.Length > 0)
                    {
                        try
                        {
                            int Vara = File.ReadAllText(fi.FullName).Contains(textToSearch) ? 1 : 0;

                            if (Vara == 1)
                            {
                                workerResult[2] = files[0].FullName;
                            }
                        }
                        catch (FileNotFoundException e)
                        {

                        }
                    }
                    workerResult[0] = tfiles.ToString();
                    backgroundWorker1.ReportProgress(0, workerResult);
                    Thread.Sleep(100);
                }
                subDirs = root.GetDirectories();

                foreach (System.IO.DirectoryInfo dirInfo in subDirs)
                {
                    WalkDirectoryTree(dirInfo,filesExtension,textToSearch);
                }
            }
        }

我在文件中搜索的部分:

if (files != null)
                {
                    foreach (System.IO.FileInfo fi in files)
                    {
                        tfiles += files.Length;
                        if (files.Length > 0)
                        {
                            try
                            {
                                int Vara = File.ReadAllText(fi.FullName).Contains(textToSearch) ? 1 : 0;

                                if (Vara == 1)
                                {
                                    workerResult[2] = files[0].FullName;
                                }
                            }
                            catch (FileNotFoundException e)
                            {

                            }
                        }
                     }
                  }

在progresschanged事件中:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            string[] results = (string[])e.UserState;
            pbt.Value = e.ProgressPercentage;
            pbt.Text = e.ProgressPercentage.ToString() + "%";
            pbt.Invalidate();
            label3.Text = results[0];
            label2.Text = results[1];
            label4.Text = results[3];
            label3.Visible = true;
            label2.Visible = true;
            label4.Visible = true;
            if (results[2] != null)
            {
                ListViewCostumControl.lvnf.Items.Add(results[2]);
            }
        }

问题是我多次看到ListViewCostumControl.lvnf中的每个结果而不是一次。

有时候我会连续5次看到结果,或者7次或3次看到结果但是我希望它只添加到listView每个结果一次。

更新

我使用了一个试图找到问题的断点。 我发现有时listView会添加相同的结果(results [2])两次相同的目录同一个文件,例如Form1具有相同的目录。

这是两次添加Form1.cs时的屏幕截图。

Form1 twice

您可以两次查看同一目录和Form1。

好了,现在我检查了这个目录中的Form1文件,我看到文本Form1出现了4次。那么也许这就是问题所在?但是,如果文本Form1在Form1.cs中出现4次,它会向我显示Form1.cs有时一次有时两次,为什么它不会将相同的Form1.cs 4次添加到listView?

所以我需要找到的另一件事是,如果在一个cs文件中有更多的文本Form1,那么只有在第一次在Form1.cs中看到它时才将它报告给listView

例如,假设在目录和文件Form1中:D:\ C-Sharp \ 1 \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ Form1.cs

在此Form1.cs中,文本Form1有4次。在第3行第6行第44行第88行然后我想仅使用Form1的第3行报告结果[2]。

所以在listView中我只会看到一次:D:\ C-Sharp \ 1 \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ Form1.cs

有时我会在listView中看到两次结果:

d:\ C-夏普\ 1 \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ Form1.cs中

但有时我只在listView中看到:

d:\ C-夏普\ 1 \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ ImagesPixelsColorsComparison \ Form1.cs中

无法弄清楚为什么结果Form1.cs显示两次向listView添加两次。 为什么不4次?为什么不只是一次?

我还在WalkDirectoryTree中将for循环更改为:

for (int i = 0; i < files.Length; i++)
                {
                    tfiles += files.Length;
                    if (files.Length > 0)
                    {
                        try
                        {
                            if (File.ReadAllText(files[i].FullName).Contains(textToSearch))
                            {
                                workerResult[2] = files[i].FullName;
                            }
                        }
                        catch (FileNotFoundException e)
                        {
                            string nonono = "";
                        }
                    }
                    workerResult[0] = tfiles.ToString();
                    backgroundWorker1.ReportProgress(0, workerResult);
                    Thread.Sleep(100);
                }

但它没有改变与foreach和Vara变量相同的问题。

我还将此行从文件[0]更改为文件[i]

workerResult[2] = files[i].FullName;

但问题仍然存在,因为Form1.cs被添加到listView之前两次。

1 个答案:

答案 0 :(得分:0)

这很简单:

files = root.GetFiles(filesExtension)

SearchOption.TopDirectoryOnly以下是问题

这里需要的是subDirs = root.GetDirectories(); foreach (System.IO.DirectoryInfo dirInfo in subDirs) { WalkDirectoryTree(dirInfo,filesExtension,textToSearch); } ,因为稍后您使用

WalkDirectoryTree("C:\temp", "*.txt", "test")

您搜索已有的文件......

这是一个例子:

致电C:\temp时 我们假设您在C:\temp, C:\temp\01, C:\temp\02, C:\temp\03下有3个文件夹:

第一个电话会为您提供foreach (System.IO.DirectoryInfo dirInfo in subDirs)

中的所有文件

然后,您在此处致电SearchOption.AllDirectories,即可获得重复项。

  

您使用int Vara = File.ReadAllText(fi.FullName).Contains(textToSearch) ? 1 : 0; if (Vara == 1) { workerResult[2] = files[0].FullName; } 并删除您所在的部分   列举了SubDirs。

<强>旁注:

if (File.ReadAllText(fi.FullName).Contains(textToSearch))
{
   workerResult[2] = files[0].FullName;
}

这不是检查文件是否包含文本的非常好的方法:

Contains()

你真的不需要这里的int。如果包含字符串,{{1}}将返回布尔值true,否则返回false。