2

I have a program that logs it's progress and other data to an XML file. I want to be able to open this XML file without blocking out the writer program (not a .NET program, and I have no control over it), and to read the XML as it comes, waiting for more when it is all processed, until the EOF is received.

How can this be achieved in C#?

Note that there are 2 problems:

  1. Keeping a reading stream open without blocking the other process.
  2. Knowing when there is more input and waiting when there isn't.
Baruch
  • 20,590
  • 28
  • 126
  • 201
  • XML isn't a stream format, so this will be difficult in practice. – user7116 Nov 13 '12 at 14:51
  • Maybe you could have the log writer write to a buffer first that gets written to disk later on. Attach an observer pattern to the buffer and have it update any listners. – MrFox Nov 13 '12 at 14:52
  • In cases like this I typically prefer using a comma-separate line-based format for the logging. If you simply open and close it for every write operation, the file will be usable by the other process in between those write moments. – Frank van Puffelen Nov 13 '12 at 14:52
  • Possible duplicate http://stackoverflow.com/questions/3709104/read-file-which-is-in-use – Gratzy Nov 13 '12 at 14:53
  • @MrFox As I said, I have no control over the logging program – Baruch Nov 13 '12 at 14:56

3 Answers3

3

If I needed to do this I would do something like the following:

Use a FileSystemWatcher to get notified when the file changes. Then just read the file and parse the XML as you require.

I would go down this route as it will be difficult to read the stream as and when the external application writes to the file.

musefan
  • 47,875
  • 21
  • 135
  • 185
1

I did soemthing similar in past yielding in an OS program called Tailf. Just check the code if you want to do it yourself, or grab all from it, it should almost work for you as well, a part the fact I just care about text files.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
1

You can open a file stream without locking it by passing in the following flags:

new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

As far as waiting for the "EOF", if the other program is only writing data intermittently, you may have to put some sort of heuristics into your progress (ie. stop peeking for new data only if there's nothing new for X minutes).

Joel Martinez
  • 46,929
  • 26
  • 130
  • 185