8

One of my applications is intended to read (and only read) files which may be in use.

But, when reading a file which is already opened in, for example, Microsoft Word, this application throws a System.IO.IOException:

The process cannot access the file '<filename here>' because it is being used by another process.

The code used to read the file is:

using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
{
    // Do stuff here.
}

Of course, since the file is already used, this exception is expected.

Now, if I ask the operating system to copy the file to a new location, then to read it, it works:

string tempFileName = Path.GetTempFileName();
File.Copy(fileName, tempFileName, true);
//                                         ↓ We read the newly created file.
using (Stream stream = new FileStream(tempFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
{
    // Do stuff here.
}

What is the magic of File.Copy which allows to read the file already used by an application, and especially how to use this magic to read the file without making a temporary copy?

Arseni Mourzenko
  • 50,338
  • 35
  • 112
  • 199

2 Answers2

4

Nice question there. Have a look at this, it seems to suggest using FileShare.ReadWrite only is the key, it's worth a shot.

http://www.geekzilla.co.uk/viewD21B312F-242A-4038-9E9B-AE6AAB53DAE0.htm

Tom
  • 3,354
  • 1
  • 22
  • 25
  • Reading the comments, it seems that it works in some circumstances, and doesn't in others. In my case, with a file already opened by Microsoft Word, switching to `FileShare.ReadWrite` does not solve the problem. – Arseni Mourzenko Dec 06 '10 at 23:20
  • That's annoying, this blogpost also suggests the same thing. http://alexpinsker.blogspot.com/2005/03/how-to-read-file-thats-in-use-by.html It does appear to be a problem with it *already* being read, as opposed to subsequent reads (your app). – Tom Dec 07 '10 at 12:35
  • As a further sidenote, using File.Open returns a FileStream, as suggested here: http://aautar.digital-radiation.com/blog/?p=1292 – Tom Dec 07 '10 at 12:37
0

try removing FileShare.ReadWrite | FileShare.Delete from the FileStream constructor, or at least FileShare.Delete.

skajfes
  • 8,125
  • 2
  • 24
  • 23
  • 6
    these flags specify what *other* file streams are allowed to have, not the one that is being opened at the time - as such specifying these flags makes the lock required a *weaker* one, so your statement is wrong. – BrokenGlass Dec 06 '10 at 23:11
  • Yes, but your sharing mode must be consistent with those of other existing handles to the file. Just what's "consistent" is a little unclear to me. For example, while Word has a file open I can open it with a sharing mode of Read|Write, but not just Read on its own or Write on its own. – Ciaran Keating Dec 07 '10 at 00:07