从多行

时间:2016-06-14 14:51:14

标签: c# winforms parsing logfile

C#,Winforms: 我有一个需要解析的日志文件。此文件包含来自程序的事务请求,但程序将事务写入多行。

我需要获取ID#,如果请求因任何原因被处理或拒绝。问题是这些请求是多行的。我唯一的优点是它们包含来自记录器的相同时间戳。 (##)不可用,因为它是一个临时占位符,因此(19)可能会在整个日志中重复多次。

我正在考虑扫描PR_Request,对ID#和时间戳进行子串,但我不知道如何使流式读取器向下移动到接下来的4行并将其写成文件中的单行。

示例:

06/10/16 08:09:33.031 (1) PR_Request: IID=caa23b14, 06/10/16 08:09:33.031 (1) PR_Mon: IID=caa23b14, 06/10/16 08:09:33.031 (1) RESUME|BEGIN 06/10/16 08:09:33.031 (1) RESUME_TRIG|SC-TI

06/10/16 08:19:04.384 (19) PR_Request: IID=90dg01b, 06/10/16 08:19:04.384 (19) PR_Mon: IID=90dg01b, 06/10/16 08:19:04.384 (19) RESUME|DENIED: Access not granted.

我需要输出文件的单行。这样,我就可以用另一个程序解析它并将数据提供给数据库。

06/10/16 08:09:33.031 PR_Request: IID=caa23b14 | RESUME | BEGIN | RESUME_TRIG | SC-TI 06/10/16 08:19:04.384 PR_Request: IID=90dg01b | RESUME | DENIED: Access not granted.

编辑:

好的,我想我这里有一个基本代码。它有效,有点。这需要很长时间,因为我必须在找到与PR_Request匹配时打开另一个文件流,然后再次使用相同的fullstamp(日期+进程号)扫描该文件。然后它将寻找RESUME | BEGIN或RESUME | DENIED,然后写出它成功或失败。

有没有什么方法可以通过获取最初找到PR_Request的streamreader行来加速它,让它从另一行开始,再计算5行,然后停止它?这将有助于大大加快该计划的速度。

        string inputfolder = inputloctxt.Text;
        string outputfolder = saveloctxt.Text;
        string outputfile = @"ParsedFile.txt";

        try
        {
            string[] readfromdir = Directory.GetFiles(outputfolder);
            foreach (string readnow in readfromdir)
            {
                using (StreamReader fileread = new StreamReader(readnow))
                {
                    string fileisreading;
                    while ((fileisreading = fileread.ReadLine()) != null)
                    {
                        if (fileisreading.Contains("PR_Request"))
                        {
                            string resumed = null;
                            string fullstamp = fileisreading.Substring(1, 26);
                            string datestamp = fileisreading.Substring(1, 21);
                            string requesttype = fileisreading.Substring(27, 22);
                            string iidnum = fileisreading.Substring(53, 8);
                            using (StreamReader grabnext01 = new StreamReader(readnow))
                            {
                                string grabnow01;
                                while ((grabnow01 = grabnext01.ReadLine()) != null)
                                {
                                    if (grabnow01.Contains(fullstamp))
                                    {
                                        if (grabnow01.Contains("RESUME|BEGIN"))
                                        {
                                            resumed = "TRUE";
                                            break;
                                        }
                                        else if (grabnow01.Contains("RESUME|DENIED"))
                                        {
                                            resumed = "FALSE";
                                            break;
                                        }
                                    }
                                }
                            }
                            File.AppendAllText(outputfolder + outputfile, 
                               datestamp + " " + requesttype + " " + iidnum + " " + resumed + Environment.NewLine);
                            resumed = null;
                        }
                    }
                }
            }
        }

1 个答案:

答案 0 :(得分:1)

这听起来像你需要使用正则表达式。您可以使用名称空间 System.Text.RegularExpressions 来引用我在示例中为您创建的捕获组。

使用这些网站作为参考:

我为你开始使用正则表达式,它不漂亮,但应该完成工作。

(?:\d{2}\/\d{2}\/\d{2}\s\d{2}\:\d{2}\:\d{2}\.\d{3}\s\(\d+\)\s)(PR_Request: IID=[^,\n]+)(?:\,\n\d{2}\/\d{2}\/\d{2}\s\d{2}\:\d{2}\:\d{2}\.\d{3}\s\(\d+\)\sPR_Mon: IID=[^,\n]*\,\n\d{2}\/\d{2}\/\d{2}\s\d{2}\:\d{2}\:\d{2}\.\d{3}\s\(\d+\)\s)((RESUME|BEGIN|\||DENIED: Access not granted.)*)(?:\n\d{2}\/\d{2}\/\d{2}\s\d{2}\:\d{2}\:\d{2}\.\d{3}\s\(\d+\)\s)*((RESUME_TRIG|SC\-TI|\|)*)