4

I'm using a FileSystemWatcher to monitor a log file for changes.

The log file is written by a 3rd party application.

Once a change is triggered, I am attempting to read the file using:

using (FileStream fs = new FileStream(e.FullPath, FileMode.Open, 
    FileAccess.Read, FileShare.ReadWrite))
{
    StreamReader sr = new StreamReader(fs);
    string s = sr.ReadLine();
}

Sometimes it fails on the using line.

Other times it fails on sr.ReadLine() which I assume is happening because the 3rd party system is currently accessing the file.

I thought that by setting the FileAccess.Read I should be able to always read the file?

How can I make sure that this doesn't cause an exception, or do I need to just loop around until I can successfully read?

Ulf Kristiansen
  • 1,571
  • 3
  • 22
  • 34
CathalMF
  • 9,705
  • 6
  • 70
  • 106
  • Sometimes with this approach you can just retry a few times (sleeping a few hundred millisecs between tries). However, if the log file is written to repeatedly by the 3rd party app, you might end up breaking it by having the log file open when the 3rd party app tries to write to it... – Matthew Watson Aug 02 '13 at 16:37
  • If the other process has an exclusive lock on the file, there's not much you can do but wait for it to close the file. Fire off a timer that periodically attempts to open the file. – JosephHirn Aug 02 '13 at 16:38
  • You should close your streamreader – Sayse Aug 02 '13 at 16:54
  • @MatthewWatson Im having the problem you mentioned. The 3rd party app is failing to write occasionally because I have it locked. Any ideas for a solution? – CathalMF Aug 05 '13 at 12:44

1 Answers1

4

Short answer: Try Thread.Sleep(100) before you read and then read as fast as you can.

I thought that by setting the FileAccess.Read I should be able to always read the file?

By setting FileAccess.Read you are just saying that you need to read from the file. By setting FileShare.ReadWrite you are saying you are comfortable with the 3rd party reading and writing to the file while you read it. The exception means that the 3rd party is not comfortable with you reading while they are writing. Your first bet is to check if you can configure the 3rd party process to allow other processes to read while they write, but be aware that reading from a file that is being written to can be troublesome.

How can I make sure that this doesn't cause an exception, or do I need to just loop around until I can successfully read?

As long as the 3rd party require a exclusive lock there is no way to guarantee that you won't get the exception, but there are steps you can take to reduce the risk of conflict, mainly:

  • Read when they don't write
  • Read fast

Read when they don't write

Right now you are monitoring the file and reading as soon as the 3rd party write. Chances are they are still writing when you try to read, so you should wait a bit for them to finish. I would try Thread.Sleep 100 ms before reading, but it depends on the nature of the 3rd party process; i.e if it flushes the log every hour then you could wait more, but if it writes every second you wait less.

Read fast

See this question for tips on how to read fast. Also have in mind that right now you are reading the complete file repeatedly. If it's a big appending file you have the option of caching the part you have already read and Seek the last known position on next read. This way you will just skip what you have read before.

Community
  • 1
  • 1
Ulf Kristiansen
  • 1,571
  • 3
  • 22
  • 34