【问题标题】:When searching for a text in a file i'm getting the same result multiple times why?在文件中搜索文本时,我多次得到相同的结果,为什么?
【发布时间】:2016-06-15 21:49:07
【问题描述】:

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

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 会添加相同的结果(结果 [2])两次相同的目录相同的文件,例如 Form1 具有相同的目录。

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

你可以看到同一个目录和Form1两次。

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

所以我需要找到的另一件事是,如果在 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-Sharp\1\ImagesPixelsColorsComparison\ImagesPixelsColorsComparison\ImagesPixelsColorsComparison\Form1.cs

但有时我在 listView 中只看到一次:

D:\C-Sharp\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 变量相同的问题。

我还将这一行从 files[0] 更改为 files[i]

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

但是问题依然存在,和之前两次将Form1.cs添加到listView中一样。

【问题讨论】:

  • if(!lvnf.Item.Contains(result[2]) =&gt; Add ?!
  • 首先这一行给我错误:if(!ListViewCostumControl.lvnf.Items.Contains(results[2])) 错误5 'System.Windows.Forms.ListView.ListViewItemCollection 的最佳重载方法匹配.Contains(System.Windows.Forms.ListViewItem)' 有一些无效参数和错误 6 参数 1:无法从 'string' 转换为 'System.Windows.Forms.ListViewItem'
  • 第二个原因是什么原因在 WalkDirectoryTree 方法中给出相同的多个结果?我想不通。
  • 好吧……很奇怪。要调试,我建议将所有命中转储到 1 个列表,当 File.ReadAllText(files[i].FullName).Contains(textToSearch)true 时将其保存到列表中。调试时此列表是否包含重复项?
  • 好的,我做了测试,我在 form1 的顶部和递归方法 WalkDirectoryTree 中为列表创建了一个实例,当它为真时,我将项目添加到列表中,并且仅添加一次每一次 !!!因此,使用 List 可以正常工作,但由于某种原因,将结果报告给 listView 会显示两次。所以我猜我报告进度结果的方式或我构建结果数组的方式有问题。

标签: c# .net winforms


【解决方案1】:

很简单:

WalkDirectoryTree("C:\temp", "*.txt", "test") //Lets say you start like this

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 下有 3 个文件夹:

第一次调用会为您提供C:\temp, C:\temp\01, C:\temp\02, C:\temp\03 中的所有文件

然后,你打电话给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;
}

这不是检查文件是否包含文本的好方法,请这样做:

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

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

【讨论】:

  • 我现在添加到 GetFiles 行 SearchOption.TopDirectoryOnly 但得到了相同的结果。我做了:files = root.GetFiles(filesExtension, SearchOption.TopDirectoryOnly);
  • 也许问题出在我对文件执行的循环中?使用 Vara 变量?
  • @מנימנחם 您检查过您的驱动器吗?你确定这些文件只存在一次吗?
  • 我将更新我的问题,并附上截图以便于理解。
  • 不,它们只有一次。我现在也使用了一个断点,有时它会向 listView 添加相同的项目两次相同的结果但并非总是相同的两次,这很奇怪。
猜你喜欢
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 2019-09-07
相关资源
最近更新 更多