25

I've searched all over but can't find an answer to this question. I understand that FileAccess deals with file access on the machine and FileShare deals with the share, but I can't find an explanation of how exactly it comes together and how they impact one another.

For example, if I have

using ( FileStream fs = new FileStream( pathName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) )

does that mean that users on the machine can only read the file whilst users remotely accessing the folder can read and write to the file? Additionally, what would the impact be in using

using ( FileStream fs = new FileStream( pathName, FileMode.Open, FileAccess.Read ) )

Where I haven't specified the FileShare?

Ben Voigt
  • 260,885
  • 36
  • 380
  • 671
Storm
  • 1,298
  • 3
  • 11
  • 26

3 Answers3

45

FileAccess says what you are going to do with the file. Pretty easy to understand, you'll know you are going to read or write.

FileShare is the much trickier one since it requires you to step into the shoes of another programmer. It determines what another process can do if it also has the file opened. Two processes accessing a file can be very troublesome, you'll need to reason through the possible failure modes. The value you pick is strongly correlated to the type of the file and the access you want. Breaking it down by what you are going to do:

FileAccess.Read

There is never any trouble if another process also reads from the file. So FileShare.Read is the default choice.

You may need FileShare.ReadWrite if another process has already opened the file for writing. It already gained write access so you can never open the file yourself with just FileShare.Read, you can't deny writing since that other process was first, you'll be denied access instead. This generally only comes to a good on a text file, the kind where you can be sure that the other process is only ever appending text to the end of the file. A log file is the very common scenario. Still possibly tricky, it matters exactly when that process flushes changes to the file. You might observe partially written lines of text, beware of this.

FileAccess.Write

You cannot use FileShare.Write or FileShare.ReadWrite. Since that would allow two processes writing to the file at the same time, the file content will be a jumble of output from both programs. A possible workaround is these processes arbitrating access to the file, ensuring only one of them can ever access the file at the same time. Normally implemented by a named mutex.

You can use FileShare.Read if it is text file, same scenario I described above with the log file. The default choice otherwise should be FileShare.None

FileAcces.ReadWrite

Not that common, only used if you write binary data and use Seek(). There is no hope that any other process could ever read the file correctly while you are doing this, assuming they don't arbitrate access themselves, you must use FileShare.None.

Hans Passant
  • 873,011
  • 131
  • 1,552
  • 2,371
3

The FileShare has nothing to do with drives shared over a network - it indicates how other processes can access the file.

If the first process opens the file with FileShare.Read, other processes can open the file with FileAccess.Read, but another process cannot open the file with FileAccess.Write in that case.

C.Evenhuis
  • 24,516
  • 2
  • 54
  • 68
  • So let me try see if I can get this right. FileShare is how I play with the other kids, FileAccess is how I play with myself? In other words, FileAccess is ONLY dealing with my application? If that is correct, then what would happen when I omit the FileShare attribute? – Storm Aug 02 '14 at 18:13
  • 2
    @Storm that's mostly right. FileAccess is not for your app, though, but for this FileStream instances. The OS does not differentiate between processes and threads when it comes to files. When you omit that attribute you get some default that nobody remembers. So don't do that. – usr Aug 02 '14 at 18:38
  • 1
    MSDN says: "`FileShare.Read` is the default for those `FileStream` constructors without a `FileShare` parameter." – Ben Voigt Aug 02 '14 at 19:02
  • @Ben where did you find that please? I just rechecked the MSDN for [FileStream](http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k("System.IO.FileStream.%23ctor");k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true) and it doesn't say anything about that there, what am I missing? – Storm Aug 02 '14 at 19:09
  • 1
    http://msdn.microsoft.com/en-us/library/47ek66wy%28v=vs.110%29.aspx and http://msdn.microsoft.com/en-us/library/tyhc0kft%28v=vs.110%29.aspx and even on this overload where it makes no sense at all: http://msdn.microsoft.com/en-us/library/ms143395%28v=vs.110%29.aspx – Ben Voigt Aug 02 '14 at 19:12
  • Thanks for that, the others [like the base constructor page](http://msdn.microsoft.com/en-us/library/System.IO.FileStream.FileStream(v=vs.110).aspx) doesn't show it. Why does it then not also show what the defaults for BufferSize and FileOptions is? Because that's then my next question since currently I'm specifying those as well `using ( FileStream fs = new FileStream( pathName, FileMode.Append, FileAccess.Write, FileShare.None, 4096, FileOptions.SequentialScan ) )` – Storm Aug 02 '14 at 19:35
  • @Storm I never look at the docs to answer such questions. Just decompile the code. The defaults are immediately apparent. – usr Aug 02 '14 at 19:43
  • What's the best / right way to decompile to see please? I don't want to just go cowboy on the code – Storm Aug 03 '14 at 08:20
1

FileShare has nothing to do with Windows file shares. It talks about sharing files on the same machine only. It specifies what other file handles coming after you are maximally able to do. Also, existing handles are compared to it to decide whether you can open the file or not.

FileAccess specifies your access rights.

usr
  • 162,013
  • 33
  • 219
  • 345
  • These answers are so close together, the other one just had a bit more explanation on FileAccess so I decided to expand further on that one – Storm Aug 02 '14 at 18:17
  • 1
    Not only file handles coming after you. It gets checked against already opened handles as well. Whenever file access comes into conflict with another handle file share, the newly opened handle loses. – Ben Voigt Aug 02 '14 at 19:04