【问题标题】:Reading line by line through text file taking abnormally long time逐行读取文本文件耗时异常
【发布时间】:2016-09-30 13:50:18
【问题描述】:

我有一个问题,我需要逐行阅读文本文件,如果满足某些条件,则将每一行放入一个字符串或另一个字符串中。我遇到的问题是这需要很长时间,我只是想知道是否有更快的做事方式。我已经做了很多关于如何做到这一点的研究,这是我能想到的最好的。谢谢。 (每次都附加两个字符串,因为必须在之后立即将两个字符串输出到文本文件)。

内容在一个巨大的文本文件中,其中一条信息以“aaa”开头的一行开始。我必须通过查找行何时以“aaa”开头来查看分隔这些信息的文本文件。将一条信息与 fullStr1 或 fullStr2 分开的标准是索引 29 处的字符是空格(“ “) 或不。谢谢。

        Using reader As StreamReader = New StreamReader(file)
            Dim line As String = reader.ReadLine
            Do While (Not line Is Nothing)
                If line.Substring(0, 3) = "aaa" AndAlso line.Substring(29, 1) <> " " Then
                    Do
                        fullStr1 = fullStr1 & line & vbCrLf
                        line = reader.ReadLine
                    Loop While (Not line Is Nothing AndAlso line.Substring(0, 3) <> "aaa")
                ElseIf line.Substring(0, 3) = "aaa" AndAlso line.Substring(29, 1) = " " Then
                    Do
                        fullStr2 = fullStr2 & line & vbCrLf
                        line = reader.ReadLine
                    Loop While (Not line Is Nothing AndAlso line.Substring(0, 3) <> "aaa")
                End If
            Loop
        End Using

【问题讨论】:

    标签: .net vb.net visual-studio streamreader


    【解决方案1】:

    如果您有足够长的文本文件,则无论您做什么都需要一段时间来扫描。但是您可以做的一件事应该有所帮助,那就是使用StringBuilder。它正是针对这种情况而设计的,比将一个巨大的字符串一块一块地连接起来要高效得多。

    Dim builder1 As New StringBuilder()
    Dim builder2 As New StringBuilder()
    
    Using reader As StreamReader = New StreamReader(file)
       Dim line As String = reader.ReadLine
       Do While (Not line Is Nothing)
          If line.Substring(0, 3) = "aaa" AndAlso line.Substring(29, 1) <> " " Then
             Do
                builder1.AppendLine(line)
                line = reader.ReadLine
             Loop While (Not line Is Nothing AndAlso line.Substring(0, 3) <> "aaa")
          ElseIf line.Substring(0, 3) = "aaa" AndAlso line.Substring(29, 1) = " " Then
             Do
                 builder2.AppendLine(line)
                 line = reader.ReadLine
             Loop While (Not line Is Nothing AndAlso line.Substring(0, 3) <> "aaa")
          End If
       Loop
    End Using
    

    我还要小心你的循环不会“卡住”,因为外部循环中没有 reader.ReadLine 调用。如果它进入外部循环并且当前行不是以“aaa”开头的情况,那么它将永远循环不做任何事情。要做到这一点,您只需要在第一行没有“aaa”。

    【讨论】:

    • +1。 string 实例的不断重新分配和销毁很可能是导致运行缓慢的罪魁祸首。
    【解决方案2】:

    一个非常快速和简单的解决方案是对变量 line 和 fullStr 使用 StringBuilder 类型而不是 String 类型。 (见https://msdn.microsoft.com/en-us/library/ms172824.aspx)。 字符串是不可变的,这意味着每次您为 line 或 fullStr 变量赋值时,您并没有真正更新内存中的变量值,而是废弃先前分配的内存并为变量分配新的内存空间并将新值分配给新的内存空间。这是很多开销,会影响应用程序的性能。

    【讨论】:

    • 感谢您提到 StringBuilder,我在几分钟内就完成了,节省了几个小时。
    【解决方案3】:

    我知道这不是最佳分辨率,但它可能会更快一些。我总是把每一行放在一个列表中。这有助于使字符串不那么长,然后我可以逐行浏览。但是当你逐行读取时,任何更大的文件都需要时间,因为它正在读取文件的每一行/字节。

    Private Function ReadInFile(ByVal strFile As String) As List(Of String)
        Dim strLineTemp As String = ""
        Using read As New StreamReader(strFile)
            While read.Peek <> -1
                strLineTemp = read.ReadLine()
                If strLineTemp.Trim <> "" Then
                    lstFileData.Add(strLineTemp)
                End If
            End While
        End Using
        Return lstFileData
    End Function
    

    【讨论】:

      【解决方案4】:

      这是你想要的吗?我将条件交换为使用正则表达式并删除了内部循环。尽管我会将字符串连接换成“StringBuilder”,但我在一个大文件上的内存不足。

      Dim regex As Regex = New Regex("aaa.{25} .*")
          st.Start()
          Using reader As StreamReader = New StreamReader(file)
              Dim line As String = reader.ReadLine
              Do While (Not line Is Nothing)
                  If regex.Match(line).Success = False Then
      
                      fullStr1 = fullStr1 & line & vbCrLf
                      line = reader.ReadLine
                  Else
                      fullStr2 = fullStr2 & line & vbCrLf
                      line = reader.ReadLine
      
                  End If
      
              Loop
      
          End Using
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-13
        • 2020-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-02
        相关资源
        最近更新 更多