FileStream RealFileLog = new FileStream(@"c:\bridge.log", FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] b = new byte[1024]; //насколько я правильно понял это буфер для записи прочитанных данных, в моей задаче важен размер
//этого буфера, когда буфер заполнен, он обнуляется или что с ним происходит?
string sPattern = "Deadlock";
while (RealFileLog.Read(b, 0, b.Length) > 0)
{
//возможно ли найти мой патерн с помощью String.IndexOf("мой патерн")
//понимаю что IndexOf - метод String, но может есть какой-то не черезжопный метод:)))
//или все же использовать System.Text.RegularExpressions.Regex.IsMatch(temp.GetString(b), sPattern,
//System.Text.RegularExpressions.RegexOptions.IgnoreCase)
//хочу использовать поменьше using'гов - System.Text.RegularExpressions, чтоб программа не была громоздкой
}
Организовать эффективную работу с текстовыми файлами
В NET'е совсем не давно, такую прогу лучше конечно в с++ (выигрыш быстродействия) писать, но пишу ради практики (изучения языка).
Долго бродил в просторах MSDN'а, гугла, решил все же создать тему.
VS 2008, C#, FrameWork 3.5
Есть задача - организовать эффективную работу (анализ) текстовых файлов (логов работы программ)
Поясняю - есть разные логи: лог сервера БД, лог работы вертушки и т. д., необходимо искать в этих логах ошибки (список ошибок известен, назовем их патерны), и дальше сообщать мол имеется ошибка.
Размеры файлов (логов) разные - от 2 Мб до 60 Мб, поэтому хочу реализовать такую схему:
1) читаем "реальный" лог программы, натыкаемся на ошибку
2) Запоминаем позицию ошибки (насколько я понял метод FileStream.Seek)
3) Всю строку с ошибкой записываем в "локальный" лог файл (для каждого "реального" файл лога, свой "локальный" лог файл в который сбрасываются ошибки)
4) сигнализируем о наличии ошибки
5)при следующей вычитке "реальный" лога программы, начинаем читать с запомненной позиции (насколько я понял метод FileStream.position)
значение position думаю держать первой строкой в "локальном" логе файла.
Начал пытаться осуществлять, сразу возникло несколько вопросов:
1) правильный ли наметил путь (может опытные люди найдут в чем поправить)?
2) вопросы в коде:
Код:
Код:
public void RunAnalyzeLog()
{
for (int i = 0; i < CountTask; i++)
{
if (Tasks.State == 1)
{
FileStream FSRealFileLog = new FileStream(@Tasks.PathToLog, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader RealFileLog = new StreamReader(FSRealFileLog, Encoding.Default);//Encoding.Default - тут приходиться манипулировать кодировкой чтоб патерн находился, можно как то програмно вычислять кодировку?
RealFileLog.BaseStream.Position = Tasks.FilePosition;
//MessageBox.Show(Convert.ToString(RealFileLog.BaseStream.Position));
while ((line = RealFileLog.ReadLine()) != null)
{
for (int k = 0; k < Tasks.Paterns.Length; k++)
{
if (Regex.IsMatch(line, Tasks.Paterns[k], RegexOptions.IgnoreCase))
{
StreamWriter LocalLog = new StreamWriter(PathToApp + @"\Logs\" + Tasks.TaskName, true, Encoding.Unicode); // а здесь для универсальности я записываю в юникод, в редакторе файл просматриваеться нормально, но RichTextBoxLogs.LoadFile(Application.StartupPath + @"\Logs\" + Tasks.TaskName, RichTextBoxStreamType.PlainText); отображает крокозяблы, можно как то побороть?
LocalLog.Write(line + "\n");
LocalLog.Close();
Tasks.NowErrors++;
//labelCountErrors.Text = Tasks.NowErrors.ToString();
checkedListBoxLogs.Items = Tasks.TaskName + " - " + Tasks.NowErrors.ToString();
}
}
}
Tasks.FilePosition = RealFileLog.BaseStream.Position;
RealFileLog.Close(); // надо ли закрывать StreamReader ??
}
}
}
{
for (int i = 0; i < CountTask; i++)
{
if (Tasks.State == 1)
{
FileStream FSRealFileLog = new FileStream(@Tasks.PathToLog, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader RealFileLog = new StreamReader(FSRealFileLog, Encoding.Default);//Encoding.Default - тут приходиться манипулировать кодировкой чтоб патерн находился, можно как то програмно вычислять кодировку?
RealFileLog.BaseStream.Position = Tasks.FilePosition;
//MessageBox.Show(Convert.ToString(RealFileLog.BaseStream.Position));
while ((line = RealFileLog.ReadLine()) != null)
{
for (int k = 0; k < Tasks.Paterns.Length; k++)
{
if (Regex.IsMatch(line, Tasks.Paterns[k], RegexOptions.IgnoreCase))
{
StreamWriter LocalLog = new StreamWriter(PathToApp + @"\Logs\" + Tasks.TaskName, true, Encoding.Unicode); // а здесь для универсальности я записываю в юникод, в редакторе файл просматриваеться нормально, но RichTextBoxLogs.LoadFile(Application.StartupPath + @"\Logs\" + Tasks.TaskName, RichTextBoxStreamType.PlainText); отображает крокозяблы, можно как то побороть?
LocalLog.Write(line + "\n");
LocalLog.Close();
Tasks.NowErrors++;
//labelCountErrors.Text = Tasks.NowErrors.ToString();
checkedListBoxLogs.Items = Tasks.TaskName + " - " + Tasks.NowErrors.ToString();
}
}
}
Tasks.FilePosition = RealFileLog.BaseStream.Position;
RealFileLog.Close(); // надо ли закрывать StreamReader ??
}
}
}
3 вопроса в коде.
и Еще один:
нормально ли (правильно) при каждом анализе лога создавать FileStream FSRealFileLog = new... и т д
или более правильно где то выше их раз создать, а потом просто инициализировать и закрывать?