2016-06-19 29 views
1

タイトルが示すように、私は同時にファイルを読み書きしようとしています。私はこのトピックを研究しましたが、私の発見した答えは私のプログラムの状況のた​​めに私のために働いていないようです。私は複数のFileSystemWatchersを使用して、常にネットワーク上のフローを通過する大量のファイルを追跡しています。ファイルが自分のフローの各部分を通過すると、ファイル名とそのフォルダ内で作成された時刻を示すテキストファイル(フロー内の1つのテキストファイル)が更新されます。ファイルが通過しているときや、トラッカーのテキストファイルに書き込んでいるときは、予測できません。私の目標は、ユーザーがまったく同じ時刻に書き込まれているテキストファイルからの読み込みを試みた場合に、ファイルを同時に読み書きできるようにすることです。どうすればこれを達成できますか?StreamWriterでTextWriterを同時に使用して読み込み/書き込みを同時に実行する

//Write to File 
    private void WriteToFile(string info,string path,string tr) 
    { 
     if (!File.Exists([email protected]"\"[email protected])) 
     { 
      var myFile = 
      File.Create(path + @"\" + @tr); 
      myFile.Close(); 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info,true); 
      tw.Close(); 
     } 
     else if (File.Exists(path + @"\" + @tr)) 
     { 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info); 
      tw.Close(); 
     } 
    } 
+0

ファイルを読む責任を負うコードを質問に追加できますか?ありがとう! – Snoopy

+0

FileStreamを使用する場合は、ファイルの一部をロックすることができます。https://msdn.microsoft.com/en-us/library/system.io.filestream.lockまたはFileShare.Noneオプションを使用してください。 – Slai

答えて

1

あなたは複数の試みがある時点でファイルの書き込み/読み込みさせることができますが、あなたはまだ操作がで次々に実行されることを確実にしたいと言っているように見えるためにほのめかしている状況読み取りまたは書き込みが呼び出された正しい順序。

操作が同期されている読み書き込みがちょうど方法を中心にlockまたはMonitorを置くことであろうことを保証する一つの簡単な方法を。あなたの書き込み方法については、次のコードを試してみてください。

private readonly object _locker = new object(); 

// write the file 
private void WriteToFile(string info, string path, string tr) 
{ 
    Monitor.Enter(this._locker); 

    try 
    { 
     if (!File.Exists(path + @"\" + @tr)) 
     { 
      var myFile = 
      File.Create(path + @"\" + @tr); 
      myFile.Close(); 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info, true); 
      tw.Close(); 
     } 
     else if (File.Exists(path + @"\" + @tr)) 
     { 
      TextWriter tw = new StreamWriter(path + @"\" + @tr, true); 
      tw.WriteLine(info); 
      tw.Close(); 
     } 
    } 
    finally 
    { 
     Monitor.Exit(this._locker); 
    } 
} 

その後、私はファイルを読み込むために非常によく似た構文を使用します。 Monitorが何をするか

// read the file 
private string ReadFile(string path) 
{ 
    Monitor.Enter(this._locker); 

    try 
    { 
     // read the file here... 
    } 
    finally 
    { 
     Monitor.Exit(this._locker); 
    } 
} 

は、進行write操作が完了(およびその逆)になるまで、ファイルはreadされないようです。これにより、古いデータを読み取ったときに古いデータが取得されず、新しいデータ(まだ読み取られていないデータ)も上書きされなくなります。この方法は、常にファイルの整合性を検証します。

+0

これはどのように機能しますか?私が理解すれば、ファイルを読み書きするまでファイルをロックしていますか?そして読者の中で、私はまだ単純なファイルストリームリーダーを使用しますか? –

+0

@MarshalAlessi実際にはオブジェクトにロックをかけるだけです。したがって、 'ReadFile'メソッドは、' WriteFile'が実行されている間は実行できません。あなたは実際には、 '_locker'オブジェクトでブロックしています。つまり、ビジー状態のスレッドが 'Monitor.Exit()'に到達してロックを放棄するまで、指定された時刻に 'Monitor'を通過するスレッドは1つだけです。それは理にかなっていますか? – Snoopy

+0

説明ありがとうございました!私はもう1つの質問がありますが、私はこのメソッドをテストしましたが、奇妙なことに、新しいファイルごとに4行のデータを生成します。 IEは、テキストファイルに書き込むときに同じ行を4回複製します。これは何が原因でしょうか? –

関連する問題