如何检查文件中的部分字符串?

时间:2013-11-13 23:50:13

标签: c#

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

    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, ""));
                }
            } 
          }

它有效,但问题是它只查找文件中的完整单词。例如,如果我查找“帐户”一词,并且该文件包含“帐户”字样,我的代码就可以使用。如果文件包含“AccountCode”一词,我的搜索将无法找到它。有办法解决吗?

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

4 个答案:

答案 0 :(得分:3)

这是一种非常圆润的方式。只需加载整个文件内容并使用IndexOf

var content = File.ReadAllText(path);

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

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

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

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

答案 1 :(得分:1)

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

您可能需要:如果该列表包含包含 ObjectName 的项目。所以改为:

if (fileItems.Any(e => e.Contains(ObjectName)))

答案 2 :(得分: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 =>
        {
            ...
        }

答案 3 :(得分:0)

检查字符串的内容时,不要忘记为字符串

实现比较器
If(string.Contains( value ,StringComparer.CurrentCultureIgnoreCase ))

// Apply logic...

经常被遗漏......