0

我正在尝试编写一个代码来检查给定目录和子目录下的所有文件是否有从网页传递的字符串。截至目前,我有这个代码:

    private void ProcessDirectory(string targetDirectory, string origDirectory, string ObjectName)
    {
        string[] fileEntries = Directory.GetFiles(targetDirectory);
        string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);

        foreach (string fileName in fileEntries)
        {
            ProcessFile(fileName, origDirectory, ObjectName);
        }

        foreach (string subdirectory in subdirectoryEntries)
           ProcessDirectory(subdirectory, origDirectory, ObjectName);
    }

    private void ProcessFile(string path, string origDirectory, string ObjectName)
    {
        if (ObjectName != "")
        {
            var fileLines = File.ReadAllLines(path);
            List<string> fileItems = new List<string>(fileLines);

            if (fileItems.Contains(ObjectName))
            {
                string sExt = Path.GetExtension(path).ToLower();

                if (sExt == ".txt")
                {
                    listTextFiles.Items.Add(path.Replace(origDirectory, ""));
                }
            } 
          }

它可以工作,但问题是它只在文件中查找完整的单词。例如,如果我查找单词“Account”,并且文件包含单词“Account”,我的代码将起作用。如果文件包含单词“AccountCode”,我的搜索将找不到它。有没有办法解决它?

另一个问题,如何添加一个计数器,在进程结束时显示在给定目录和所有子目录下检查了多少文件。

4

4 回答 4

3

这是一种非常迂回的做法。只需加载整个文件内容并使用IndexOf

var content = File.ReadAllText(path);

if (content.IndexOf(ObjectName) > -1) {
    // rest of your code here
}

无需逐行加载,用这些行初始化一个全新的列表,并检查每一行。

正如您所要求的,这也提供了部分搜索的好处。

您可以通过仔细审核您消耗的内存量来极大地改善这一点。您的方法和我在此处提供的方法都可能会分配大块内存,只是在条件检查后它们无用。考虑使用 aStringBuilder并在每个文件中重新使用它。

于 2013-11-13T23:54:11.863 回答
1

if fileItems.Contains(ObjectName))将根据条件搜索列表fileItems如果该列表包含等于 的项目 ObjectName

您可能想要:如果该列表包含包含 ObjectName. 所以改成这样:

if (fileItems.Any(e => e.Contains(ObjectName)))
于 2013-11-13T23:53:50.033 回答
0

检查字符串的内容时,不要忘记为字符串实现一个比较器

If(string.Contains( value ,StringComparer.CurrentCultureIgnoreCase ))

// Apply logic...

它经常被忽略...

于 2013-11-14T01:12:22.630 回答
0

回答第二个问题。因为您在这里使用递归,所以您需要声明一个属性或类级别变量并在您的 ProcessFile 方法中递增它,例如:

public int NumberOfMatches { get; set; }

ProcessFile...
{
 if (fileItems.Contains(ObjectName))
 {
      NumberOfMatches++;
 }

作为旁注,这里没有理由使用递归,您只需一次调用即可获取所有文件:

string[] allFiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);

如果性能是一个问题,您也可以考虑多线程:

   Parallel.ForEach(allFiles,
        new ParallelOptions { MaxDegreeOfParallelism = 4 },
        allFiles =>
        {
            ...
        }
于 2013-11-14T01:05:55.643 回答