在.net vb中解析文本文件的最佳(性能)方法是什么?

时间:2015-04-24 10:49:25

标签: regex vb.net string parsing

我有一个处理JBOSS日志的应用程序。它检索应用程序的活动用户。 Log有一行代表哪个用户请求了哪个操作。

日志中的行是这样的:

[23 apr 2015 17:14:58,268] [INFO ] [Module: Search (845903)] -- Request is performing by User 'BILL GATES' using the 'App Session' Session

日志文件很大。 〜1MB。很多行。并非每一个都指用户操作。 我现在所做的是阅读LINE by LINE文件,找到一个有" User"在其中输入字符串,然后从该行中检索名称。

有效。但是 - 它的速度很慢,而且表现看起来相当沉重。我正在处理5个这样的日志文件。

我正在研究如何更好地更快地完成这项工作?正则表达式?有什么建议吗?

谢谢!

更新:代码

     If System.IO.File.Exists(tmpusr063) = True Then
        Dim objReader As New System.IO.StreamReader(tmpusr063)
        Do While objReader.Peek() <> -1
            'Get the timestamp from the line
            TextLine = objReader.ReadLine()
            time = Microsoft.VisualBasic.Left(TextLine, 21)
            time = Microsoft.VisualBasic.Right(time, 20)
            tm = DateTime.ParseExact(time, "dd MMM yyyy HH:mm:ss", CultureInfo.CreateSpecificCulture("nl-NL"))
            span = DateTime.Now.TimeOfDay - tm.TimeOfDay
            ' end of getting the timestamp in a Time type. span - is a difference between NOW and when the time on the line
            If CInt(span.Hours) < user4timeh Then 'if the time of the line is withing the limits i set  in hours
                If CInt(span.Minutes) < user4timem Then ' in minutes then start disassembling the line 
                    If TextLine.Contains("User") And TextLine.Contains("'") Then ' if line contains User = line has a username
                        linsplt = TextLine.Split("'") 'retrieving the user name
                        If users.Contains(linsplt(1)) = False Then 
                            users(usrnmbr) = linsplt(1) 'assemble an array of user names
                            usrnmbr += 1
                        End If
                    End If

                End If
            End If

        Loop
        objReader.Close()
    End If

BUT!我想我找到了一个罪魁祸首....日志有很多线,我不需要那些用户&#34;用户&#34;不存在。但在我的逻辑中 - 我仍然采用EACH行并从中检索时间,然后检查它是否是用户名的相关行......该死的:)我将移动{{1语句up :)不聪明:))

1 个答案:

答案 0 :(得分:2)

这应该会好一点:

If System.IO.File.Exists(tmpusr063) = True Then
    Dim NLCultureInfo as CultureInfo = CultureInfo.CreateSpecificCulture("nl-NL")
    Dim objReader As New System.IO.StreamReader(tmpusr063)
    Do While objReader.Peek() <> -1
        TextLine = objReader.ReadLine()
            If TextLine.IndexOf("User") > -1 And TextLine.IndexOf("'") > -1 Then ' if line contains User = line has a username
            'Get the timestamp from the line
            time = TextLine.Substring(1, 20)
            tm = DateTime.ParseExact(time, "dd MMM yyyy HH:mm:ss", NLCultureInfo)
            span = DateTime.Now.TimeOfDay - tm.TimeOfDay
            ' end of getting the timestamp in a Time type. span - is a difference between NOW and when the time on the line
            If CInt(span.Hours) < user4timeh Then 'if the time of the line is withing the limits i set  in hours
                If CInt(span.Minutes) < user4timem Then ' in minutes then start disassembling the line 
                    linsplt = TextLine.Split("'") 'retrieving the user name
                        If Array.IndexOf(users, linsplt(1)) = -1 Then
                        users(usrnmbr) = linsplt(1) 'assemble an array of user names
                        usrnmbr += 1
                    End If
                End If
            End If
        End If
    Loop
    objReader.Close()
End If

我做的主要是将关于用户的条件移到循环的顶部。这样,如果你没有一个用户,你就不需要花费时间来计算时间和分钟。

我做的第二件事是在循环外创建cultureInfo对象。因为你总是使用相同的文化信息,所以最好只创建一次。

我做过的第三个也是最不重要的事情是将你的调用改为string.Contains to string.IndexOf和-1。 based on this post,它应该(理论上,无论如何),稍微好一些。它可能会累积到一些显着的差异,但我并不是真的这么认为。

YA编辑:我已纠正一行:

而不是: If users.IndexOf(linsplt(1)) = -1 Then

这是因为前一个不起作用:

If Array.IndexOf(users, linsplt(1)) = -1 Then