質問

BinaryWriterを使用して、いくつかのUINTとバイト配列からなるレコードをファイルに書き込むメソッドがあります。このメソッドは、私のプログラムの一部として1秒間に約1秒間を実行します。コードは以下のとおりです。

iLogFileMutex.WaitOne();
using (BinaryWriter iBinaryWriter = new BinaryWriter(File.Open(iMainLogFilename, FileMode.OpenOrCreate, FileAccess.Write)))
{
    iBinaryWriter.Seek(0, SeekOrigin.End);
    foreach (ViewerRecord vR in aViewerRecords)
    {
        iBinaryWriter.Write(vR.Id);
        iBinaryWriter.Write(vR.Timestamp);
        iBinaryWriter.Write(vR.PayloadLength);
        iBinaryWriter.Write(vR.Payload);        
    }
}    
iLogFileMutex.ReleaseMutex();
.

上記のコードは問題なく機能しますが、シークコールで行を削除すると、結果のバイナリファイルが破損しています。たとえば、特定の記録は完全に欠けているか、それらの一部は存在しませんが、レコードの大多数は正しく書かれていますが。そのため、バグの原因は、ファイルの現在の位置が常に最後に終わり、物事が上書きされていると繰り返し閉じている場合であると想像しています。

だから私の質問は次のとおりです.C#がファイルを開くと現在の位置が最後にあることを確認しないのはなぜですか?

PS:このバグを引き起こすのにスレッドの問題を除外しました

役に立ちましたか?

解決

問題はFileMode.OpenorcreateとViewerRecordメンバーの種類の組み合わせです。そのうちの1つ以上は固定サイズの型ではなく、おそらく文字列です。

ファイルが既に存在する場合は問題が発生します。ファイルの先頭にデータを書き始め、既存のデータを上書きします。しかし、あなたが書くものだけが偶然に既存のレコードを上書きするだけで、文字列はまった同じサイズである必要があります。十分なレコードを書いていない場合は、古いレコードのすべてを上書きしません。ファイルを読むと、最後の書面によるレコードを読んだ後に古いレコードの一部を読むことができます。あなたはしばらくジャンクを得るでしょう。

レコードを固定サイズにすると、問題を解決しないことは良いレコードを読むが、それは古いものになるでしょう。あなたが書いた新しいデータに依存する古いレコードの特定のセットがどのようなセットです。これは文字化けしたデータを読むのと同じくらい悪いはずです。

古いレコードを保存する必要がある場合は、ファイルに追加する必要があります。その後、ファイルfileMode.Createを書き換える必要があります。

他のヒント

ファイルに追加したい場合は、オープンコールでfilemode.appendを使用する必要があります。それ以外の場合、ファイルはその位置に設定されています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top