【发布时间】: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]) => 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 会显示两次。所以我猜我报告进度结果的方式或我构建结果数组的方式有问题。