63

Currently, this is how I'm opening a file to read it:

 using (TextReader reader = new StreamReader(Path.Combine(client._WorkLogFileLoc, "dump.txt")))
{
    //do stuff
}

How can I open the file in ReadOnly mode, so that if another process has the file open at the same time, my program can still read it.

Ayush
  • 41,754
  • 51
  • 164
  • 239
  • You want to open the stream in Read mode? Or do you want to set the file attribute ReadOnly? – The Scrum Meister Feb 11 '11 at 01:08
  • Note that if another process has the file open, that process still has to have enabled read sharing for you to be able to read it. If the other process opened the file with sharing denied, then even opening the file as read-only would be prevented. See the FileShare enumeration (or the Win32 equivalent) for more info. – itowlson Feb 11 '11 at 01:16

4 Answers4

150

The typical problem is that the other process has the file open for writing. All of the standard File methods and StreamReader constructors open the file with FileShare.Read. That cannot work, that denies write sharing. You cannot deny writing, the other process was first and got write access. So you'll be denied access instead.

You have to use FileShare.ReadWrite, like this:

var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
using (var sr = new StreamReader(fs))
{
    // etc...
}

Beware that you'll still have a tricky problem, you are reading a half-written file. The other process flushes data to the file at random points in time, you may well read only half a line of text. YMMV.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks. It seems this is what I was looking for. Reading a half written file won't be an issue for me because of how my program handles reading the file. – Ayush Feb 11 '11 at 01:45
  • That saved me ! As you rightly said, all other functions are opening with FileShare.Read. I was trying since quite some time to figure out with different variant of streanreader functions...! – Milind Thakkar Jun 29 '15 at 07:06
  • Worked perfectly. Exactly what I needed. Thanks! – Bruce Thompson Jan 18 '22 at 23:17
15

If you want to open the file read-only, try this:

using (TextReader reader 
   = new StreamReader(File.OpenRead(Path.Combine(client._WorkLogFileLoc, "dump.txt")))) 
{     
         //do stuff 
} 

Notice the call to File.OpenRead().

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Jay Riggs
  • 53,046
  • 9
  • 139
  • 151
4

You can set the file attribute by calling File.SetAttributes

string path = Path.Combine(client._WorkLogFileLoc, "dump.txt");
FileAttributes curAttributes = File.GetAttributes(path);
File.SetAttributes(path, curAttributes | FileAttributes.ReadOnly);
The Scrum Meister
  • 29,681
  • 8
  • 66
  • 64
  • I just wondered: setting file attributes in a process/thread. Doest it effect the other process/thread that is accessing to the file for write access? – Fredrick Gauss Mar 28 '20 at 06:46
-1

Per https://learn.microsoft.com/en-us/dotnet/api/system.io.file.openread?redirectedfrom=MSDN&view=netcore-3.1#System_IO_File_OpenRead_System_String_ File.OpenRead enables read shared access not read/write. This prevents the "other process" from being able to close/reopen/write more data as xbonez wants to permit. hans-passant addresses what was requested.

Per the referenced documentation: This method is equivalent to the FileStream(String, FileMode, FileAccess, FileShare) constructor overload with a FileMode value of Open, a FileAccess value of Read and a FileShare value of Read.