views:

20

answers:

1

If I have two threads in my Cocoa app, and (let's say), I'm reading from file X on the disk with an NSData +dataWithContentsOfFile:, and another thread is concurrently updating or replacing that same file X, with, say a -writeToPath:atomically:?

I'm unfamiliar with what Cocoa's standard file read/writes modes are. Could the read operation see corruption mid-file? If so, what is the standard way around this? Use POSIX functions to allow effectively multiple-readers but only one exclusive writer?

Thanks for insight that bridges my understanding between the Cocoa API and the underlying filesystem.

+1  A: 

Could the read operation see corruption mid-file?

Not if you set atomically to YES. What that does is writes the data to a temporary file, then overwrites the intended destination with the temporary file. This is atomic (on local file-systems, anyway) because it's just a quick edit to the directory.

The read might only get part of the data if you were to start writing to the intended destination immediately and weren't finished yet—i.e., you passed atomically:NO. So, in cases like this, don't do that—pass YES.

Peter Hosey
Thanks Peter. With respect to the atomic swap-out: What happens if I've (say) opened the original file for reading, but I'm still reading it (either because it's memory-mapped and I'm taking my time or it's actually just in the middle of the read) when the atomic swap happens? Does the filesystem keep the old copy around on disk while there are readers for it? (Or does the atomic directory change block until readers are closed? Though this seems unlikely.)
quixoto
quixoto: The former. See the unlink(2) manpage, which describes what happens when a file gets deleted (unlinked). This should also be true of a file that is not specifically unlinked but gets replaced with another file, as happens in an NSData atomic write.
Peter Hosey
Peter: Perfect. Exactly the info I was looking for. Thank you for the unlink reference.
quixoto