2016-05-02 5 views
1

コードの一部が機能しなくなっています。ここには物語があります:テキストの特定のブロックを抽出し、それらのテキストのブロックだけをテキストボックスに表示する必要がある特定の書式(コード生成されているので)を持つ複数のテキストファイルがあります。たとえば、そのようなブロックの1つは「STN COMMENT」「END COMMENT」です。このファイルは2つ、3つ、または10つのブロックを持つことができ、異なるタイプのブロックを持ちます。ここでは、COMMENTはQUESTION、ANNOUNCEMENT、またはTRAFFICに置き換えられます。すべてが対応する "END"で終わります。ここに私が試した第1のコードセグメントがある:StreamReaderがSystem.NullReferenceExceptionをスローします

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 

これは、次の例外を生成しました。 CでGSPASEC_Net_Control.ReviewNetLogFrm.ParseLog(のInt32データ型、のInt32 SORTTYPE)で :\ Users \ユーザーKE4NHWのVisual Studio 2010 \ドキュメント\プロジェクト\ \ GSPASECネットコントロール\ GSPASECネットコントロール\ ReviewNetLogFrm.vb:私が持っているライン238

上のコードでマークされた行238。しかし、ここではそのブロックの出力は、次のとおりです。

STN発表:午後06時50分54秒KE4NHW

ASDFASDFASDFASDF

STN発表:午後06時50分57秒KE4NHW

DFADFADFASWERASDF

STNアナウンス:18:51:01 KE4NHW

GHSDETGJNHSDFAW34ASDFG

この出力には、テキストボックスに入力する必要がある "END ANNOUNCEMENT"行がありませんが、それ以外の場合はすべてのアナウンスが表示されます。それは、テキストブロック(終わりの行)ごとに1行を欠き、そのnullreferenceexceptionをスローします。それ以外の場合は、少なくとも私たちはすべてのテキストを取得する必要が表示される終了ステートメントを取得することができます取得する必要があります。

は、私はまた、すべてが同じエラーを生成し、無成功し、次の変更を試してみました:

変更ではありませんが(行は何もありません)...エンドラインは何も

なくなるまで... DOループする一方で

行は何もないまでですかすることを変更しました...ループ

私の最新のテストバージョンはこれです:

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

あなたは前の行を読み込んだ後に 'line'が何もないかどうかをチェックしません。 – Plutonix

+0

デバッガでコードを実行すると、数分で問題の原因がわかります。あなたはそれを使うことを学ぶべきです。 –

+0

あなたはまた、最初の行の内容をチェックしていません( 'Dim line ....')ので、その行の1つがそれらのブロックの開始を知らせるので、コードはそれを見逃します。読み込み中のファイルが小さい場合は、ファイル全体を読み込んで1行ずつ処理することができます。それらが大きい場合は、結果として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

私は不正なブロックの可能性が何であるか知らないが、私は単にendTokenとして「END」のために見えるかもしれませんので、最後のどのタイプのブロックでもキャプチャが停止します。それは再同期のチャンスを与えます。

またはブロック終了信号には、の任意のブロックの開始が含まれている可能性があります。その場合は、一貫性のために「END ANNOUNCEMENT」を手動で追加するか、不正な形式のブロックが検出されたことに注意する必要があります。これらの内容には、非ANNOUCEMENTデータが含まれる場合があります。

また、無制限にUIコントロールを使用する代わりにStringBuilderを使用します。文字列は不変なので、Textプロパティに追加すると何度も何度も再構築されます。これは、キャプチャされたラインが特定のポイントを超えたときに、スピードアップする必要があります。

+0

あなたがここで示した解決策は完全に機能します!私はEnvironment.NewLineを文字列ビルダーに追加するなど少し修正する必要がありましたが、それ以外は完璧です!他の人の質問に答えるのにまだ熟練していないので、私の評判は十分に高くはありません。他の誰かがこれをアップヴォートすることができれば、それは優れた解決策です。そんなにPlutonixと、これで私を助けてくれた皆さん、ありがとう! Grrのテキスト解析は苦痛です。 –

+0

これは動作します: 'sr As StreamReader = New StreamReader(TmpFileName) Dim line As String = sr.ReadLine() Do もしあればline.Contains( "STNのCOMMENT")すると ドゥ txtNetLog.Text = txtNetLog.Text + NL +ライン ライン= sr.ReadLine() ループline.Containsまで( "ENDコメント") txtNetLog.Text = txtNetLog .Text + nl 終了の場合 行= sr.ReadLine ループが何もないまで 終了使用中 –

+0

申し訳ありませんが、私が使うことができなければ、行が壊れます。どこに行くのかを示します。それはほとんど動作しますが、調整が可能な改行では少しずれています。全体の問題は、Do ... Loop Isntil行が何もない行の上にあるreadline()を持っていたようです。それはline.Contains(token)がNothingを解析しようとしていたために中断する原因となりました。うわー、それは配置に関するすべてです。私はプログラムのロジックをブラッシュアップする必要があります...誰もが私を助けてくれてありがとう、それは今働いている! –

関連する問題