web-dev-qa-db-ja.com

「別のプロセスで使用中」の例外が発生した場合でも、どのようにしてファイルを読み取ることができますか?

VB.NETまたはC#では、別のプログラムで使用されているテキストファイルの内容を読み取ろうとしています(それがポイントです、実際にはプログラムを停止できないか、テキストファイルへの書き込みを停止し、現在、別のプログラムのテキストファイルにあるものを定期的に読み取りたい)。

これは私が使用しているコードです(VB.NET)

Dim strContents As String
Dim objReader As StreamReader
objReader = New StreamReader(FullPath)
strContents = objReader.ReadToEnd()
objReader.Close()

またはC#の場合:

var objReader = new StreamReader(FullPath);
var strContents = objReader.ReadToEnd();
objReader.Close();

ただし、上記はIO例外をスローします。「プロセスは別のプロセスで使用されているため、ファイル 'file.txt'にアクセスできません。」このシナリオに回避策はありますか?

44
Frustrated Guy
FileStream logFileStream = new FileStream("c:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader logFileReader = new StreamReader(logFileStream);

while (!logFileReader.EndOfStream)
{
    string line = logFileReader.ReadLine();
    // Your code here
}

// Clean up
logFileReader.Close();
logFileStream.Close();

コードの元のソース

67
Development 4.0

私は魚をやります。 FileShareモードは重要です。書き込み共有を許可する必要があります。ファイルを書き込んでいるプロセスがすでに書き込みアクセス権を取得しているため、これを拒否することはできません。 StreamReader()コンストラクターはFileShare.Readを使用し、異なる値を使用するオプションはありません。代わりにStreamReader(Stream)コンストラクターを使用するのが実際の回避策です。

ただし、この共有モードはコードにも影響することに注意してください。他のプロセスがファイルをフラッシュする時期を予測することはできません。最後に読んだ行には、テキスト行の一部のみが含まれている場合があります。再びファイルバッファがフラッシュされると、後で残りの行が表示されます。明らかにこれはロジックを台無しにする可能性があります。

8
Hans Passant

ファイルに追加している他のアプリケーションによってファイルが開かれたFileShareモードに依存します。他のアプリケーションがファイルを開いているとき、他のアプリケーションがファイルにアクセスするためのFileShareモードを指定しました。このFileShareモードは読み取り、書き込み、両方、削除、これらすべて、またはなしでした。

他のアプリケーションが指定したものとまったく同じFileShareモードを指定する必要があります。他のアプリケーションが読み取りのみを許可している場合、FileShare.Read;を使用し、読み取りと書き込みの両方を許可している場合は、FileShare.ReadWriteを使用します。

StreamReaderFileShare.Readモードのみを使用するため、これが適切でないとすでに想定できます。だから、次のようにReadWriteを試してください:

FileStream fs = new FileStream(FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader reader = new StreamReader(fs);
4
Barbara

既に開いているファイルでこれがどのように動作するかはわかりませんが、これによりアプリケーションがファイルをロックできなくなります。

FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);

それが役に立てば幸い!

2
Brosto