查找文件中字符串的最快方法

时间:2011-08-24 23:46:53

标签: c# string

我有一个不超过10KB的日志文件(文件大小最多可达2 MB),我想查找文件中是否至少出现一组这些字符串。这些字符串将在不同的行上,如

  

ACTION:.......

     

INPUT:...........

     

结果:..........

如果文件中存在上述一组,我至少需要知道。我已经做了大约100次测试(每次日志不同,所以我重新加载并阅读日志),所以我正在寻找最快和下注的方式来做到这一点。

我在论坛中查找找到最快的方法,但我认为我的文件对于那些问题来说太大了。

Thansk寻找。

5 个答案:

答案 0 :(得分:5)

我会逐行阅读并检查条件。一旦你看到一个组,你就可以退出。这样您就不需要将整个文件读入内存。像这样:

    public bool ContainsGroup(string file)
    {
        using (var reader = new StreamReader(file))
        {
            var hasAction = false;
            var hasInput = false;
            var hasResult = false;
            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                if (!hasAction)
                {
                    if (line.StartsWith("ACTION:"))
                        hasAction = true;
                }
                else if (!hasInput)
                {
                    if (line.StartsWith("INPUT:"))
                        hasInput = true;
                }
                else if (!hasResult)
                {
                    if (line.StartsWith("RESULT:"))
                        hasResult = true;
                }

                if (hasAction && hasInput && hasResult)
                    return true;
            }
            return false;
        }
    }

此代码检查是否有以ACTION开头的行,然后是INPUT,然后是RESULT。如果这些顺序不重要,那么您可以省略if () else if ()检查。如果该行未以字符串开头,请将StartsWith替换为Contains

答案 1 :(得分:3)

这是一种可行的方法:

StreamReader sr;
string fileContents;

string[] logFiles = Directory.GetFiles(@"C:\Logs");

foreach (string file in logFiles)
{

    using (StreamReader sr = new StreamReader(file))
    {

        fileContents = sr.ReadAllText();

        if (fileContents.Contains("ACTION:") || fileContents.Contains("INPUT:") || fileContents.Contains("RESULT:"))
        {
             // Do what you need to here
        }

    }
}

您可能需要根据您的确切实施需求做一些变化 - 例如,如果单词跨越两行,该行是否需要以单词开头等等。

<强>加

替代逐行检查:

StreamReader sr;
string[] lines;

string[] logFiles = Directory.GetFiles(@"C:\Logs");

foreach (string file in logFiles)
{

    using (StreamReader sr = new StreamReader(file)
    {

        lines = sr.ReadAllLines();

        foreach (string line in lines)
        {        
            if (line.Contains("ACTION:") || line.Contains("INPUT:") || line.Contains("RESULT:"))
            {
                // Do what you need to here
            }
        }

    }
}

答案 2 :(得分:2)

看看How to Read Text From a File。您可能还想查看String.Contains()方法。

基本上你会循环遍历所有文件。对于逐行读取的每个文件,并查看是否有任何行包含1个特殊的“章节”。

答案 3 :(得分:2)

在效率方面,您没有太多关于文本文件的选择。最简单的方法肯定是遍历每一行数据。当您在字符串中抓取一行时,将其拆分为空格。然后将这些单词与您的单词匹配,直到找到匹配项。然后做你需要的任何事情。

我不知道如何在c#中执行此操作,但在vb中它将类似于......

Dim yourString as string
Dim words as string()
Do While objReader.Peek() <> -1
   yourString = objReader.ReadLine()
   words = yourString.split(" ")
   For Each word in words()
      If Myword = word Then
         do stuff
      End If
   Next
Loop

希望有所帮助

答案 4 :(得分:0)

此代码示例在大文本文件中搜索字符串。单词包含在HashSet中。它将找到的行写到临时文件中。

        if (File.Exists(@"temp.txt")) File.Delete(@"temp.txt");

        String line;
        String oldLine = "";
        using (var fs = File.OpenRead(largeFileName))
        using (var sr = new StreamReader(fs, Encoding.UTF8, true))
        {
            HashSet<String> hash = new HashSet<String>();
            hash.Add("house");
            using (var sw = new StreamWriter(@"temp.txt"))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    foreach (String str in hash)
                    {
                        if (oldLine.Contains(str))
                        {
                            sw.WriteLine(oldLine); 
                            // write the next line as well (optional)
                            sw.WriteLine(line + "\r\n");                                    
                        }
                    }
                    oldLine = line;
                }
            }
        }