限制VB.NET

时间:2018-12-04 06:47:48

标签: string vb.net list

我正在使用StreamReader.ReadLine()循环浏览日志文件以查找错误。当我发现错误时,我需要查看前面的代码以查看发生了什么。

但是由于StreamReader不允许我阅读前几行,因此我需要保留前几行的记录。

我一直在使用lineStrings.Add(readfile.ReadLine()),其中lineStringsList(Of String),而readFileStreamReader

这很好用,但是我的一些日志文件很大,因此列表太大了。错误详细信息仅出现在任何错误的前10行中,因此当列表已包含10个元素时,当我添加新行时,有什么办法让List(Of String)丢弃旧行?

我看过堆栈和队列,但只是让自己感到困惑。

谢谢!

3 个答案:

答案 0 :(得分:1)

以下几行内容(手工输入的伪代码,但您应该能够翻译):

Dim SB As New StringBuilder
Dim LineCount as Integer = 0

Do While Stream.End
  Dim CurLine = ReadNextLineFromYourStream()
  SB.Append(CurLine)
  LineCount += 1
  If LineCount > 10 Then RemoveFirstLineFromSB
  If ErrorFound Then YouHaveYourLast10LinesIn(SB.ToString())
Loop

StringBuilder删除第一行就像SB.Remove(0, SB.IndexOf(vbCrLf))或您使用的任何行终止符一样简单。

答案 1 :(得分:1)

我将创建一个StringBuffer类,以仅保留最后n个字符串。

Public Class StringBuffer
    implements IEnumerable(Of String)

    Private _internalBuffer As LinkedList(Of String)

    Public Sub New(ByVal size As Integer)
        Size = size
        _internalBuffer = New LinkedList(Of String)()
    End Sub

    Public Property Size As Integer

    Public Sub Add(ByVal str As String)
        _internalBuffer.AddFirst(str)
        If _internalBuffer.Count > Size Then _internalBuffer.RemoveLast()
    End Sub

    Public Function GetEnumerator() As IEnumerator(Of String) Implements IEnumerable(Of String).GetEnumerator
        Return _internalBuffer.GetEnumerator()
    End Function

    Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
        Return _internalBuffer.GetEnumerator()
    End Function
End Class

我们使用LinkedList作为内部数据结构来实现Add操作的O(1)时间复杂度(这也可能会删除旧项)。
迭代后,您将首先获得最新条目。

答案 2 :(得分:1)

根据对过程的描述,可以使用List(Of String)Queue(Of String)保留从日志文件读取的最后N行。

如果要考虑性能,那么List(of String)可能比Queue(Of String)快一点。

使用两个类的示例:
注意:发现错误时,列表(lineStrings)将包含MaxElements + 1个元素。最后一行是包含错误的行,其余MaxElements行包含错误说明或任何错误说明。

Dim MaxElements As Integer = 10
Dim lineStrings As List(Of String) = new List(of String)

'(...)
'Open the file stream using a StreamReader
lineStrings.Add(readfile.ReadLine())
If lineStrings.Last().Contains([Error]) Then
    'Process the error using the lineStrings items
    'Clear the List if the content is not required anymore
    lineStrings.Clear()
End If
If lineStrings.Count > MaxElements Then lineStrings.RemoveAt(0)

您可以使用Queue(Of String)做同样的事情:

Dim lineStrings As Queue(Of String) = new Queue(of String)(MaxElements)

lineStrings.Enqueue(readfile.ReadLine())
If lineStrings.Last().Contains([Error]) Then
    'Process the error using the lineStrings items
    'Clear the Queue if needed/preferable
    lineStrings.Clear()
End If
If lineStrings.Count > MaxElements Then lineStrings.Dequeue()

进行速度测试,添加100,0001,000,000元素,检查错误并从列表中删除第10个元素,不进行处理(使用.exe文件编译为发行版):

100,000 elements (average):
List(Of String):  21 ms
Queue(Of String): 29 ms

1,000,000 elements (average):
List(Of String):  206 ms
Queue(Of String): 298 ms