それが書かれた直後にファイルを読む私はすべてのゼロ(.net)を取得します

StackOverflow https://stackoverflow.com/questions/4742158

  •  12-10-2019
  •  | 
  •  

質問

ディレクトリが書かれたらすぐにファイルをロードする必要があるプログラムがあります。 FilesystemWatcherに、ディレクトリの変更を通知してもらいました。変化したものをイベントをチェックするのではなく、ファイルをリストし、見つけたものをすべて処理し始めます。

まだ書かれているファイルを読み取ろうとすることを防ぐために、次のようなコードがあります。

try {
    fs = fi.Open(FileMode.Open, FileAccess.ReadWrite,
                    FileShare.None);
    message = new byte[fs.Length];
    int br = fs.Read(message, 0, (int)fi.Length);
}
catch (Exception e) {
    // I'll get it next time around
    return;
}
finally {
    if (fs != null)
        fs.Close();
}

問題は、一部のファイルである200分の1のファイルでは、プログラムがすべてのゼロを読み取ることです。ファイルの長さは正しいですが、コンテンツはすべてゼロバイトのように見えます。後者を確認すると、実際の正しいデータが含まれていることがわかります。ファイルを開いている方法がファイルへの早期アクセスを防ぐと思いました。

DOSコマンド「infile_0* dropdir」(実行ごとに約100ファイル)を使用してディレクトリにファイルをコピーすることでこれをテストしています。プログラムは時々2つの中央にジャンプします。

信頼できるようにこれをコーディングする方法に関するアイデアはありますか?

アップデート: 私はライティングプログラムをコントロールしていません - それは何でもかもしれません。防御的にコーディングしなければならないようです。

役に立ちましたか?

解決

あなたは人種の状態にぶつかります。明確に修正しない限り、ここから(ネットワーク化されたファイルシステムなど)悪化するだけです。

「whaty.tmp」名を使用してそれぞれを書き込むプログラムにプログラムを作成してみてください。次に閉じてから名前を変更してください。読んでいるときは、.tmpファイルを無視します。

または、ディレクトリに「Sentinel」またはそのようなものという名前のゼロ長さのファイルを保持します。別のファイルの書き込みが成功したたびにセンチネルファイルを書き直すためにファイルを書き込むプログラムを取得します。次に、変更日/時間が> =センチネルファイルの変更日/時刻があるファイルを読み取ろうとしないでください。

または、ファイルのライターを制御できない場合は、現在のシステムの日付/時刻に対して各ファイルの変更日/時刻を確認してください。ファイルを適切な量(小さい場合は数秒、大きい場合は長くなります)を読み込もうとします。

幸運を。これは首の悪名高い痛みです。

他のヒント

さて、私は@ollie Jonesによる以前の投稿に同意しません。

あなたはすでにファイルへの排他的アクセスを確立したので、レース状態の問題はありません。

作家の行動をもっと注意深く調べるべきだと思います。また、読み取り専用のファイルアクセスの干渉を減らしてください。すべてのアクセスを共有してください。

fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

これは読み取りに失敗する可能性がありますが、書き込みエラーを減らします。いつ安全に読むかを決定するには、ファイルの時間やファイルのサイズなどを確認できます。その後、多くのファイルが書かれている場合、2番目のファイルが作成された後、最初のファイルの読み取りを開始できます。

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