Jared が言うように、ファイルを開いている他のエンティティが共有読み取りを許可しない限り、これを行うことはできません。Excel では、書き込み用に開いているファイルであっても、共有読み取りが可能です。したがって、FileShare.ReadWriteパラメーターを使用してファイル ストリームを開く必要があります。
FileShare パラメータはよく誤解されています。ファイルの他のオープナーができることを示します。これは、過去のオープナーだけでなく、将来のオープナーにも適用されます。FileShare は、以前のオープナー (Excel など) に対する遡及的な禁止ではなく、現在のオープンまたは将来のオープンで違反してはならない制約と考えてください。
現在ファイルを開こうとしている場合、FileShare.Read は、「以前のオープナーが読み取り専用で開いた場合にのみ、このファイルを正常に開いてください」と言います。Excel によって書き込み用に開かれているファイルに FileShare.Read を指定すると、 Excel が書き込み用に開いているため、制約に違反するため、ファイルを開くことができません。
Excel では書き込み用にファイルが開かれているため、正常に開くには、FileShare.ReadWrite を使用してファイルを開く必要があります。FileShare パラメーターのもう 1 つの考え方は、「他のユーザーのファイル アクセス」を指定することです。
ここで、現在他のアプリで開かれていないファイルを開くという別のシナリオを考えてみましょう。FileShare.Read は、「将来のオープナーは読み取りアクセスでのみファイルを開くことができます」と述べています。
論理的には、これらのセマンティクスは理にかなっています。FileShare.Read は、他の人が既にファイルを書き込んでいる場合はそのファイルを読みたくないことを意味し、既に読んでいる場合は他の人にファイルを書きたくないことを意味します。FileShare.ReadWrite は、別の人がファイルを書き込んでいる場合でも、ファイルを読み取る意思があることを意味し、読み取り中に別のオープナーにファイルを書き込んでも問題ありません。
これにより、複数のライターが許可されることはありません。FileShare は、データベースの IsolationLevel に似ています。ここでの望ましい設定は、必要な「一貫性」の保証によって異なります。
例:
using (Stream s = new FileStream(fullFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
...
}
また、
using (Stream s = System.IO.File.Open(fullFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
}
補遺:
System.IO.FileShare に関するドキュメントは、少し簡潔です。正確な事実を知りたい場合は、Win32 CreateFile 関数のドキュメントを参照してください。FileShare の概念がよりよく説明されています。