2011-11-23 17 views
5

私のアプリはデータをプルしてテキストファイルに追加しますが、プログラムでテキストファイルの最初の行を見て、それが次のものと一致するかどうかを調べる必要がありますテキスト:テキストファイルの先頭に1行追加する

のDateTime、VirtualIP、VirtualPort、VirtualName、DestinationIP、DestPort、ステータス、最初の行ではない場合、それは、その後、正常な機能(以下スニペットを)やっていきなければ

を希望上記と同じですが、私は現在そこにあるものを上書きせずに上記の最初の行に挿入したいと思います。これどうやってするの? (本質的にすべてを1行下にプッシュするので、最初の行に追加することができます)... btwこれはexcelで開くことができるcsvファイルとして保存されています。

try 
{ 
    // ... 
    for (int j = 0; j < memberStatus.Result.Count; j++) 
    { 
     VirtualMemberStatus status = memberStatus.Result[j]; 

     //text += String.Format("Name: {4}, Member: {0}:{1}, Status: {2}, Desired: {3}" + Environment.NewLine, status.Member.Address, status.Member.Port, status.EffectiveStatus, status.DesiredStatus, virtualKey.Key); 
     text += String.Format("{5},{4},{0},{1},{2},{3}" + Environment.NewLine, status.Member.Address, status.Member.Port, status.EffectiveStatus, status.DesiredStatus, virtualKey.Key.Replace(":", ","), DateTime.UtcNow); 
    } 
} 
catch 
{ 
    //ERROR CODE 2 
    //MessageBox.Show("Error occurred, check device name (case senstive) and admin group. This error may also occur due to connection loss, try again."); 
    errors += String.Format("{0} Error Code: 2, Error occurred, check device name (case senstive) and admin group. This error may also occur due to connection loss, try again." + Environment.NewLine, DateTime.UtcNow); 

} 

this.resultsTextBox.Text = text; 

このファイルは大量に削除されることはありませんが、そのファイルの上に正しい列名を付けたい場合は、このファイルを削除してください。すなわち:

DateTime,VirtualIP,VirtualPort,VirtualName,DestinationIP,DestPort,Status,Desired 
+1

タイトルの最後には本当に「c#」は必要ありません。タグはあなたのためにそれを行います。 –

+0

ええ、私は知っているが、より良い可視性のためにそれをした – KPS

+0

タグはあなたのためにそれを世話する。あなたがしていることは、あなたのタイトルを読みにくくすることです。他の人がそれを読んで助けてくれる可能性は低いです。これはニュースグループやディスカッションフォーラムではありません。 –

答えて

8

ファイル全体を書き直す必要があります。

  1. は(一時的に!)新しいを開い書き込み線(パフォーマンスが懸念される場合、ブロック・バッファリングを考慮)
  2. フラッシュと近い出力ファイル
  3. 、各入力行に対して
  4. 書き込みヘッダ行を提出します
  5. エラーがなければ、テンポラリファイルをその場所に移動します(名前を変更して)。

(IO)エラーはここ

はそのようなことを行うためのコードであるプロセスを途中であった場合に問題を防ぐことができ、この手順:サンプルコードも作成すること

using (var input = new StreamReader("input.txt")) 
    using (var output = new StreamWriter("input.txt.temp")) 
{ 
    output.WriteLine("headerline"); // replace with your header :) 

    var buf = new char[4096]; 
    int read = 0; 
    do 
    { 
     read = input.ReadBlock(buf, 0, buf.Length); 
     output.Write(buf, 0, read); 
    } while (read > 0); 

    output.Flush(); 
    output.Close(); 
    input.Close(); 
} 

File.Replace("input.txt.temp", "input.txt", "input.txt.backup"); 

注意をバックアップ。 1つの可能な改善点は、FileStream(...., FileMode.CreateNew)を明示的にインスタンス化し、その名前でファイルがすでに存在する場合に一時ファイルを上書きしないようにすることです。

もう1つの解決策は、System.IO.Path.GetTempFileName()を使用することです。しかし、File.Replaceは、一時的なフォルダーが別のボリューム/ファイルシステム上にある可能性があるため、効率的でアトミックにならなくなる可能性があります。

+0

コードサンプルが追加されました – sehe

+0

これは機能しますが、ツールを再度実行すると、行が先頭に再び挿入されます。私はそれを一度だけ望んでいますが、ヘッダーにマッチしてこのプロセスをスキップすれば、どのようにして0行目に読み込み、読むことができるでしょうか? – KPS

+0

これは私のために働いた、私はちょうど最初の行が私のヘッダーと一致するかどうかを確認するためにif/elseステートメントを行った。ありがとうございました! – KPS

0

これらの単語をマッチングするかどうかを調べるには、最初の位置に検索する必要があります。このコードスニペットでは、探しているものが得られます。

Dim filePath As String = "file.txt" 
    Dim bufferSize As Integer = 8129 

    Dim textToMatch As String = "DateTime,VirtualIP,VirtualPort,VirtualName,DestinationIP,DestPort,Status,Desired" 
    Dim textByte As Byte() = ASCIIEncoding.ASCII.GetBytes(text) 

    Dim buffer As Byte() = Nothing 

    Dim fs As FileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite) 
    fs.Read(buffer, 0, bufferSize) 


    Dim i As Int32 = fs.Seek(0, SeekOrigin.Begin) 
    fs.Position = i 

    If fs.Position.Equals(textToMatch) Then 

    Else 
     fs.Write(textByte, 0, textByte.Length) 
    End If 

    fs.Flush() 
    fs.Close() 
関連する問題