2016-05-02 31 views
1

我有一些困难得到一段代码工作。以下是叙述:我有多个具有特定格式的文本文件(因为它们是代码生成的),我需要提取特定的文本块并仅显示文本框中的文本块。例如,一个这样的块将是“STN COMMENT”“END COMMENT”。这个文件可能有两个,三个或甚至10个这样的块,并且将具有不同类型的块,其中评论将被替换为问题,公告或交通。全部以相应的“结束”结束。下面是第一代码段我尝试:StreamReader抛出System.NullReferenceException

'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数据类型的Int32 SortType)在C:\用户\ KE4NHW \文档\ Visual Studio 2010的\项目\ GSPASEC网络控制\ GSPASEC网络控制\ 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;除此之外,如果我可以显示结束语句,那么至少我们会得到所有需要拉取的文本。

我自己也尝试没有成功以下变化,都产生了同样的错误:

改变了虽然不是(行没有)......结束在操作循环,直到行没有

改变,这样做直到行没有...循环

我最新的测试版本是这样的:

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

您在读取上一行之后,您没有检查'行'是否为空。 – Plutonix

+0

单步执行调试器中的代码将在几分钟内向您显示问题的原因。你应该学会使用它。 –

+0

您还没有检查第一行读取的内容('Dim line ....'),因此该行表示其中一个块的开始,代码将错过它。如果正在读取的文件很小,则可以读取整个文件并逐行处理;如果它们很大,则应该使用StringBuilder作为结果...和调试器的同上 – Plutonix

回答

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属性意味着重复它。当捕获的线条超出特定点时,这应该加快速度。

+0

您在这里给出的解决方案非常完美!我不得不稍微调整它,比如在字符串生成器中添加Environment.NewLine append,但除此之外完美无缺!我的声望还不够高,因为我还没有足够的技巧来回答别人的问题,但如果是这样的话,我肯定会赞扬这个。如果其他人可以赞成这一个请做,因为这是一个很好的解决方案。非常感谢Plutonix和所有帮助过我的人! Grr文本解析是一个痛苦。我想了一会儿我要去已突破或进口正则表达式... –

+0

这也适用于: '使用SR作为StreamReader的=新的StreamReader(TmpFileName) 昏暗行的String = sr.ReadLine() 做 如果line.Contains( “STN COMMENT”)然后 执行 txtNetLog.Text = txtNetLog.Text + NL +线 线= sr.ReadLine() 循环直到line.Contains( “END COMMENT”) txtNetLog.Text = txtNetLog .Text + nl End If line = sr.ReadLine 循环直到线没有什么 最终使用# –

+0

对不起,我假设你会知道在哪里放置如果没有我可以使用,线断裂;以表明他们去了哪里。这几乎可以工作,但对可以调整的换行符稍微有些偏离。似乎整个问题都有一个readline()正上方的Do ... Loop直到线没有。它导致line.Contains(标记)因为试图解析Nothing而中断。哇,这完全是关于安置。我需要刷新程序逻辑......感谢大家帮助我,现在正在工作! –

相关问题