StreamReader抛出System.NullReferenceException

时间:2016-05-02 23:50:41

标签: vb.net vb.net-2010 streamreader

我在使用一段代码时遇到了一些困难。这是叙述:我有多个具有特定格式的文本文件(因为它们是代码生成的),我需要提取特定的文本块并在文本框中仅显示那些文本块。例如,一个这样的块将是“STN COMMENT”“END COMMENT”。此文件可能包含两个,三个甚至10个此类块,并且将具有不同类型的块,其中COMMENT将替换为QUESTION,ANNOUNCEMENT或TRAFFIC。全部以相应的“END”结束。这是我尝试的第一个代码段:

'block to parse only this user's announcements
'dl is variable alias for: Environment.NewLine + Environment.NewLine
txtNetLog.Text = "" 'clears the textbox
TmpFileName = logPath + ByCall + "-" + Format(Now, "dd-MMM-yyyy") + ".tmp" 'sets filename with path defined in module
Try
    Using sr As StreamReader = New StreamReader(TmpFileName)
    Dim line As String = sr.ReadLine()
        While Not (line Is Nothing)
            line = sr.ReadLine()
            If line.Contains("STN ANNOUNCEMENT") Then '***This is line 238 from exception
                Do
                    txtNetLog.Text = txtNetLog.Text & line + dl
                    line = sr.ReadLine()
                Loop Until line.Contains("END ANNOUNCEMENT")
             End If
         End While
     End Using
 Catch ex As Exception
     Dim msg As String = "Error: Failure Parsing Temp File For Announcements. Contact Developer" + dl + ex.ToString
     Dim title = "Error in StreamReader"
     Dim errorFile As System.IO.StreamWriter
     Dim errorFileName As String = logPath + "Errors.txt"
     errorFile = My.Computer.FileSystem.OpenTextFileWriter(errorFileName, True)
     errorFile.Write(msg)
     errorFile.Close()
     MsgBox(msg, MsgBoxStyle.ApplicationModal, title)
 End Try

这产生了以下异常:

System.NullReferenceException:未将对象引用设置为对象的实例。    在GSPASEC_Net_Control.ReviewNetLogFrm.ParseLog(Int32 DataType,Int32 SortType)C:\ Users \ KE4NHW \ Documents \ Visual Studio 2010 \ Projects \ GSPASEC Net Control \ GSPASEC Net Control \ ReviewNetLogFrm.vb:238行

我在上面的代码中标记了238行。但是,这是该块的输出:

STN公告:18:50:54 KE4NHW

ASDFASDFASDFASDF

STN公告:18:50:57 KE4NHW

DFADFADFASWERASDF

STN公告:18:51:01 KE4NHW

GHSDETGJNHSDFAW34ASDFG

此输出缺少应放在文本框中的“END ANNOUNCEMENT”行,否则它会获得所有公告。它错过了每个文本块一行(结束行)并抛出了nullreferenceexception;除此之外,如果我可以显示结束语句,那么至少我们将拥有所有需要提取的文本。

我也尝试了以下更改但没有成功,都产生了同样的错误:

更改了“不是”(行无效)...结束时要执行...循环直到行无效

将其更改为Do Until line Is Nothing ... Loop

我最新的测试版本是:

    txtNetLog.Text = ""
    'block to parse only this user's Comments
    TmpFileName = logPath + ByCall + "-" + Format(Now, "dd-MMM-yyyy") + ".tmp"
    Try
        Using sr As StreamReader = New StreamReader(TmpFileName)
            Dim line As String = sr.ReadLine()
            Do Until line Is Nothing
                line = sr.ReadLine()
                If line.Contains("STN COMMENT") Then
                    Do Until line.Contains("END COMMENT")
                        txtNetLog.Text = txtNetLog.Text + line + nl + nl
                        line = sr.ReadLine()
                    Loop
                End If
            Loop
        End Using
    Catch ex As Exception
        Dim msg As String = "Error: Failure Parsing Temp File For Comments. Contact Developer" + nl + nl + ex.ToString
        Dim title = "Error in StreamReader"
        MsgBox(msg, MsgBoxStyle.ApplicationModal, title)
        ErrorLogWriter("ErrorLog.txt", msg)
    End Try

同样的事情。不在文本框中放置“END COMMENT”,并抛出相同的异常。我的想法不是强迫try块只是让异常沉默,但这肯定会引起问题。对这一个有任何想法吗?

1 个答案:

答案 0 :(得分:0)

看看这是否有效:

Dim sb As New StringBuilder
Dim startToken = "STN ANNOUNCEMENT"
Dim endToken = "END ANNOUNCEMENT"
Dim line As String

Using sr As StreamReader = New StreamReader("C:\Temp\LogData.Txt")

    Do Until sr.EndOfStream
        line = sr.ReadLine
        If line.StartsWith(startToken) Then
            sb.AppendLine(line)
            Do Until sr.EndOfStream OrElse line.StartsWith(endToken)
                line = sr.ReadLine
                sb.AppendLine(line)
            Loop
        End If
    Loop

End Using

tbLog.Text = sb.ToString

Sample data used

我不知道格式错误的块的可能性是多少,但我可能只是寻找" END"作为endToken,以便任何类型的块的结束将停止捕获。它给了它重新同步的机会。

或者块结束信号可能包括任何块的开始。在这种情况下,您可以手动添加" END ANNOUNCEMENT"为了均匀性或其他注意到检测到畸形块。这些内容可能包括非ANNOUCEMENT数据。

此外,它使用StringBuilder而不是无休止地搞乱UI控件。字符串是不可变的,因此附加到Text属性意味着一遍又一遍地重建它。当捕获的线超过某一点时,这应该加快速度。