Самый быстрый способ найти строки в файле - PullRequest
5 голосов
/ 25 августа 2011

У меня есть файл журнала, который не превышает 10 КБ (размер файла может превышать 2 МБ), и я хочу выяснить, встречается ли хотя бы одна группа этих строк в файлах. Эти строки будут в разных строках, как,

ДЕЙСТВИЕ: .......

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

РЕЗУЛЬТАТ: ..........

Мне нужно знать, по крайней мере, существует ли в файле одна группа выше. И я делал это примерно 100 раз для теста (каждый раз журнал отличается, поэтому я перезагружаю и читаю журнал), поэтому я ищу самый быстрый и лучший способ сделать это.

Я посмотрел на форумах, чтобы найти самый быстрый способ, но я не думаю, что мой файл слишком велик для этих рассуждений.

Спасибо за поиск.

Ответы [ 5 ]

5 голосов
/ 25 августа 2011

Я бы прочитал это построчно и проверил условия. Как только вы увидели группу, вы можете выйти. Таким образом, вам не нужно читать весь файл в память. Как это:

    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.

3 голосов
/ 25 августа 2011

Вот один из возможных способов сделать это:

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 голосов
/ 25 августа 2011

У вас нет особого выбора с текстовыми файлами, когда дело доходит до эффективности.Самый простой способ - это циклически проходить по каждой строке данных.Когда вы берете строку в строку, разделите ее на пробелы.Затем сопоставьте эти слова со своими словами, пока не найдете соответствие.Тогда делай что хочешь.

Я не знаю, как это сделать в 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

Надеюсь, что помогает

2 голосов
/ 25 августа 2011

Взгляните на Как читать текст из файла .Возможно, вы также захотите взглянуть на метод String.Contains () .

По сути, вы будете перебирать все файлы.Для каждого файла прочитайте построчно и посмотрите, содержит ли какая-либо из строк одну из ваших специальных «Разделов».

0 голосов
/ 30 августа 2018

Этот пример кода ищет строки в большом текстовом файле. Слова содержатся в 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;
                }
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...