views:

71

answers:

3

If I'm writing a simple text log file from multiple processes, can they overwrite/corrupt each other's entries?

(Basically, this question http://stackoverflow.com/questions/1154446/is-file-append-atomic-in-unix but for Windows/NTFS.)

A: 

From this MSDN page on creating and opening Files:

An application also uses CreateFile to specify whether it wants to share the file for reading, writing, both, or neither. This is known as the sharing mode. An open file that is not shared (dwShareMode set to zero) cannot be opened again, either by the application that opened it or by another application, until its handle has been closed. This is also referred to as exclusive access.

and:

If you specify an access or sharing mode that conflicts with the modes specified in the previous call, CreateFile fails.

So if you use CreateFile rather than say File.Open which doesn't have the same level of control over the file access, you should be able to open a file in such a way that it can't get corrupted by other processes.

You'll obviously have to add code to your processes to cope with the case where they can't get exclusive access to the log file.

ChrisF
Thanks, I see what you mean, that makes sense now
Gkakk McJkakk
+2  A: 

No it isn't. If you need this there is Transactional NTFS in Windows Vista/7.

Axel Gneiting
Thanks for your response, I will keep that option in mind for the future (unfortunately this program is for Windows 2003 so I can't use TxF)
Gkakk McJkakk
+3  A: 

Even if append is atomic (which I don't believe it is), it may not give you the results you want. For example, assuming a log includes a timestamp, it seems reasonable to expect more recent logs to be appended after older logs. With concurrency, this guarantee doesn't hold - if multiple processes are waiting to write to the same file, any one of them might get the write lock - not just the oldest one waiting. Thus, logs can be written out of sequence.

If this is not desirable behaviour, you can avoid it by publishing logs entries from all processes to a shared queue, such as a named pipe. You then have a single process that writes from this queue to the log file. This avoids the conccurrency issues, ensures that logs are written in order, and works when file appends are not atomic, since the file is only written to directly by one process.

mdma
Thanks for your response and alternative solution; I've set your reply as "accepted answer" for the suggestion of using a single process with named pipes
Gkakk McJkakk