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;
}
}
}
}
}
答案 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|\|)*)