1

テキスト ファイルを開き、他のプロセスがそのファイルに書き込めないようにしたいと考えています。次の FileStream を使用してこれを実行できることを理解しています。

Dim fs As New FileStream(_FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)

このようにアクセスしたら、すべての行を読み取る必要があり (StreamReader(fs) を使用します)、ファイルに書き込む必要があります (StreamWriter(fs) を使用します)。

ここでの問題は、ファイル パスの代わりにファイル ストリームをパラメーターとして使用すると、StreamWriter で追加モードを false に設定できない (ファイル内のすべてのテキストを上書きできる) ことです。したがって、StreamWriter で書き込まれたすべてのテキストは、不要なテキストに追加されます。ファイル ストリームの代わりにパラメータとしてファイル パス (append を false に設定できる) で StreamWriter を使用すると、FileStream FileShare のためにロックアウトされます。ファイルへの読み取りと書き込みの排他的アクセスを保持しながら、既存のテキストを上書きできるようにするにはどうすればよいですか (追加モード false)。

4

1 に答える 1

2

不可能ではありません。Apppend = true で初期化された StreamWriter は実際には必要ありません。FileStream.Seek() を使用して、「ファイル ポインタ」がファイルの最後に配置されるようにするだけです。このサンプル C# コードはうまく機能しました。

using (var fs = new FileStream(@"c:\temp\test.txt", FileMode.Open,
        FileAccess.ReadWrite, FileShare.Read)) {
    var sr = new StreamReader(fs);   // NOTE: not using using
    string txt = sr.ReadToEnd();
    fs.Seek(0, SeekOrigin.End);      // Be sure
    var sw = new StreamWriter(fs);
    sw.WriteLine("appended");
    sw.Flush();
}

このコードにはかなりの不快感があることに注意してください。私は、あなたの好みの値である FileShare.Read から始めます。これは、ファイルをいじっている間に別のプロセスにファイルを読み取らせることを意味します。このプロセスは、予告なしにこのファイルに表示されるバイトについて少し混乱する可能性が高いです。FileShare.None は、コードがいかなる種類の事故も引き起こさないことを保証します。強く推奨する。

次のフラグは // 使用していないことに注意してください。StreamReader は、渡すストリームの「責任」を負うため、これは重要です。.NET コードで標準の Right Thing を実行すると、Using ステートメントがそのスコープを終了するときに、クラスはストリームを閉じます。それはあなたが望むものではありません。ファイルを保持して、書き込みできるようにしたいのです。

Seek() 呼び出しは、StreamWriter コンストラクターの Append 引数が行うことを行います。ファイルの一部を最初からランダムに上書きするのではなく、ファイルに追加していることを確認してください。追加したいので、ファイル内の古いデータが切り捨てられていることを確認しても問題ありません。

Flush コールは、ここで少し臭いです。ライターに出力バッファーを強制的にフラッシュさせるには、それを呼び出す必要があります。そうしないと、書き込みのランダムなビットがファイルから失われます。Close() を呼び出すか、Using ステートメントを使用してライターが閉じていることを確認するため、通常は問題になりません。この場合ではなく、FileStream がショットを呼び出しており、ここでファイルを適切に閉じますが、別のライターが時流に乗って書き込みたいと思っていることを知りません。

これは機能しますが、かなりの数のドグマを破ります。より一般的なパターンは、open-read + read + close、open-createnew + write + close です。また、別のプロセスがファイルを取得したために open-createnew が失敗する可能性に対処します。マルチタスク オペレーティング システムの危険性については、常に対処する準備をしておいてください。

于 2010-10-20T22:19:22.440 に答える